dart开发的8个技巧

简介: 8. 使用命名构造函数和初始化列表以获得更符合人体工程学的 API。假设您要声明一个表示温度值的类。你可以让你的类API明确支持两个摄氏和华氏两种命名的构造函数:

8. 使用命名构造函数和初始化列表以获得更符合人体工程学的 API。

假设您要声明一个表示温度值的类。

你可以让你的类API明确支持两个摄氏和华氏两种命名的构造函数:

class Temperature {
  Temperature.celsius(this.celsius);
  Temperature.fahrenheit(double fahrenheit)
    : celsius = (fahrenheit - 32) / 1.8;
  double celsius;
}
复制代码

这个类只需要一个存储变量来表示温度,并使用初始化列表将华氏温度转换为摄氏温度。

这意味着您可以像这样声明温度值:

final temp1 = Temperature.celsius(30);
final temp2 = Temperature.fahrenheit(90);
复制代码

9. getter 和 setter

Temperature上面的类中,celsius被声明为存储变量。

但是用户可能更喜欢以华氏度获取设置温度。

这可以使用 getter 和 setter 轻松完成,它们允许您定义计算变量。这是更新的课程:

class Temperature {
  Temperature.celsius(this.celsius);
  Temperature.fahrenheit(double fahrenheit)
    : celsius = (fahrenheit - 32) / 1.8;
  double celsius;
  double get fahrenheit
    => celsius * 1.8 + 32;
  set fahrenheit(double fahrenheit)
    => celsius = (fahrenheit - 32) / 1.8;
}
复制代码

这使得使用华氏度或摄氏度轻松获取或设置温度:

final temp1 = Temperature.celsius(30);
print(temp1.fahrenheit);
final temp2 = Temperature.fahrenheit(90);
temp2.celsius = 28;
复制代码

底线:使用命名构造函数、getter 和 setter 来改进类的设计。

10. 对未使用的函数参数使用下划线

在 Flutter 中,我们经常使用带有函数参数的小部件。一个常见的例子是ListView.builder

class MyListView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemBuilder: (context, index) => ListTile(
        title: Text('all the same'),
      ),
      itemCount: 10,
    );
  }
}
复制代码

在这种情况下,我们不使用(context, index)的参数itemBuilder。所以我们可以用下划线代替它们:

ListView.builder(
  itemBuilder: (_, __) => ListTile(
    title: Text('all the same'),
  ),
  itemCount: 10,
)
复制代码

注意:这两个参数是不同的 (___),因为它们是单独的标识符

11. 需要一个只能实例化一次的类(又名单例)?使用带有私有构造函数的静态实例变量。

单例最重要的特性是整个程序中只能有一个它的实例。这对于建模文件系统之类的东西很有用。

// file_system.dart
class FileSystem {
  FileSystem._();
  static final instance = FileSystem._();
}
复制代码

要在 Dart 中创建单例,您可以声明一个命名构造函数并使用_语法将其设为私有。

然后,您可以使用它来创建类的一个静态最终实例。

因此,其他文件中的任何代码都只能通过instance变量访问此类:

// some_other_file.dart
final fs = FileSystem.instance;
// do something with fs
复制代码

注意:如果您不小心,final可能会导致许多问题。在使用它们之前,请确保您了解它们的缺点。

12. 需要收集独特的set?使用集合而不是列表。

Dart 中最常用的集合类型是List.

但是列表可以有重复的项目,有时这不是我们想要的:

const citiesList = [
  'London',
  'Paris',
  'Rome',
  'London',
];
复制代码

我们可以Set在需要一组唯一值时使用 a (请注意 的使用final):

// set is final, compiles
final citiesSet = {
  'London',
  'Paris',
  'Rome',
  'London', // Two elements in a set literal shouldn't be equal
};
复制代码

上面的代码生成一个警告,因为London被包含了两次。如果我们尝试对constset执行相同的操作,则会收到错误并且我们的代码无法编译:

// set is const, doesn't compile
const citiesSet = {
  'London',
  'Paris',
  'Rome',
  'London', // Two elements in a constant set literal can't be equal
};
复制代码

当我们与台合作,我们能够获得有用的API,如uniondifferenceintersection

citiesSet.union({'Delhi', 'Moscow'});
citiesSet.difference({'London', 'Madrid'});
citiesSet.intersection({'London', 'Berlin'});
复制代码

底线:当你创建一个集合时,问问自己你是否希望它的项目是独一无二的,并考虑使用一个集合。

13.如何使用try、on、catch、rethrow、finally

try并且catch在使用基于 Future 的 API 时非常理想,如果出现问题,这些 API 可能会引发异常。

这是一个完整的示例,展示了如何充分利用它们:

Future<void> printWeather() async {
  try {
    final api = WeatherApiClient();
    final weather = await api.getWeather('London');
    print(weather);
  } on SocketException catch (_) {
    print('Could not fetch data. Check your connection.');
  } on WeatherApiException catch (e) {
    print(e.message);
  } catch (e, st) {
    print('Error: $e\nStack trace: $st');
    rethrow;
  } finally {
    print('Done');
  }
}
复制代码

一些注意事项:

  • 您可以添加多个on子句来处理不同类型的异常。
  • 您可以使用回退catch子句来处理与上述任何类型都不匹配的所有异常。
  • 您可以使用rethrow语句将当前异常向上抛出调用堆栈,同时保留堆栈跟踪
  • 您可以使用finallyFuture完成后运行一些代码,无论它是成功还是失败。

如果您正在使用或设计一些基于 Future 的 API,请确保根据需要处理异常。

14. 常见的 Future 构造函数

DartFuture类带有一些方便的工厂构造函数:Future.delayed,Future.valueFuture.error

我们可以Future.delayed用来创建一个Future等待一定延迟的。第二个参数是一个(可选的)匿名函数,你可以用它来完成一个值或抛出一个错误:

await Future.delayed(Duration(seconds: 2), () => 'Latte');
复制代码

但有时我们想创建一个Future立即完成的:

await Future.value('Cappuccino');
await Future.error(Exception('Out of milk'));
复制代码

我们可以用Future.value一个值来成功完成,或者Future.error用一个错误来完成。

您可以使用这些构造函数来模拟来自基于 Future 的 API 的响应。这在您的测试代码中编写模拟类时很有用。

15. 通用流构造器

Stream 类还带有一些方便的构造函数。以下是最常见的:

Stream.fromIterable([1, 2, 3]);
Stream.value(10);
Stream.empty();
Stream.error(Exception('something went wrong'));
Stream.fromFuture(Future.delayed(Duration(seconds: 1), () => 42));
Stream.periodic(Duration(seconds: 1), (index) => index);
复制代码
  • 用于从值列表Stream.fromIterable创建一个Stream
  • 使用Stream.value,如果你只有一个值。
  • 用于Stream.empty创建空流。
  • 用于Stream.error创建包含错误值的流。
  • 用于Stream.fromFuture创建仅包含一个值的流,该值将在未来完成时可用。
  • 用于Stream.periodic创建周期性的事件流。您可以将 a 指定Duration为事件之间的时间间隔,并指定一个匿名函数来生成给定其在流中的索引的每个值。

16. 同步和异步生成器

在 Dart 中,我们可以将同步生成器定义为一个返回 的函数Iterable

Iterable<int> count(int n) sync* {
  for (var i = 1; i <= n; i++) {
    yield i;
  }
}
复制代码

这使用sync*语法。在函数内部,我们可以“生成”或yield多个值。这些将Iterable在函数完成时返回。


另一方面,异步生成器是一个返回 a 的函数Stream

Stream<int> countStream(int n) async* {
  for (var i = 1; i <= n; i++) {
    yield i;
  }
}
复制代码

这使用此async*语法。在函数内部,我们可以yield像在同步情况下一样取值。

但是如果我们愿意,我们可以使用await基于 Future 的 API,因为这是一个异步生成器:

Stream<int> countStream(int n) async* {
  for (var i = 1; i <= n; i++) {
    // dummy delay - this could be a network request
    await Future.delayed(Duration(seconds: 1));
    yield i;
  }
}



相关文章
|
6天前
|
云安全 人工智能 算法
以“AI对抗AI”,阿里云验证码进入2.0时代
三层立体防护,用大模型打赢人机攻防战
1372 8
|
7天前
|
人工智能 Rust 运维
这个神器让你白嫖ClaudeOpus 4.5,Gemini 3!还能接Claude Code等任意平台
加我进AI讨论学习群,公众号右下角“联系方式”文末有老金的 开源知识库地址·全免费
|
6天前
|
机器学习/深度学习 安全 API
MAI-UI 开源:通用 GUI 智能体基座登顶 SOTA!
MAI-UI是通义实验室推出的全尺寸GUI智能体基座模型,原生集成用户交互、MCP工具调用与端云协同能力。支持跨App操作、模糊语义理解与主动提问澄清,通过大规模在线强化学习实现复杂任务自动化,在出行、办公等高频场景中表现卓越,已登顶ScreenSpot-Pro、MobileWorld等多项SOTA评测。
967 4
|
4天前
|
存储 弹性计算 应用服务中间件
2026年阿里云服务器新手租用全流程完整步骤教程(最新版)
2026年阿里云服务器新手租用全流程完整步骤教程,阿里云服务器提供自定义租用、一键租用、云市场租用和活动租用四种核心方式,适配不同配置需求、技术能力和预算场景。无论是需要精准配置的专业用户,还是追求快速部署的新手,都能找到合适的租用方案。以下是详细的适用场景和操作流程,助力高效上云。
298 148
|
4天前
|
人工智能 弹性计算 运维
2026年阿里云建站费用解读:三种方案价格明细、功能特性及选型建议
阿里云建站费用多少?2026年阿里云建站费用解读:三种方案价格明细、功能特性及选型建议。在数字化需求日益增长的当下,搭建网站成为个人展示、企业推广的重要途径。阿里云作为主流云服务提供商,针对不同技术基础与业务规模,推出 “自购服务器建站”“万小智 AI 模板建站”“云企业官网定制建站” 三种核心方案,价格从 38 元 / 年到数万元 / 年不等,覆盖从个人到中大型企业的全场景需求。本文基于今年最新官方定价与实测数据,从方案细节、价格体系、功能对比、场景适配等维度展开解析,为用户提供客观选型参考。
271 154
|
1天前
|
人工智能 前端开发 API
Google发布50页AI Agent白皮书,老金帮你提炼10个核心要点
老金分享Google最新AI Agent指南:让AI从“动嘴”到“动手”。Agent=大脑(模型)+手(工具)+协调系统,可自主完成任务。通过ReAct模式、多Agent协作与RAG等技术,实现真正自动化。入门推荐LangChain,文末附开源知识库链接。
242 117
|
2天前
|
机器学习/深度学习 人工智能 算法
炎鹊「Nexus Agent V1.0」:垂直领域AI应用的原生能力引擎
炎鹊AI「Nexus Agent V1.0」是垂直行业专属AI原生引擎,融合大模型、AIGA决策大脑、行业知识图谱与专属模型,打造“感知-决策-执行”闭环。支持21个行业低代码构建工具型、员工型、决策型AI应用,实现技术到业务价值的高效转化,推动AI从实验走向规模化落地。(239字)
208 1