天天看点

每个 Flutter 开发人员都应该知道的 16 个 Dart 技巧和窍门(第三节)

上一周给大家带来了flutter系列的第一二期

flutter的安装与设置(第一节)

35分钟教你学会dart(第二节)

尤其通过第二节的学习,相信大家对dart基础已经有了一定的掌握。

今天特意给大家带来我在开发中总结的dart相关的16个技巧

这是一个简单的程序,显示如何使用字符串乘法打印中国加油,甘肃挺住:

我的家乡甘肃现在生病了,但我相信他会好起来的!

是不是很酷?😉,是的我相信甘肃可以挺住的!

您可以使用它来检查长字符串如何适合<code>text</code>小部件:

考虑这个模拟 api 类,它告诉我们最新的 covid 病例数:

要同时执行所有这些futures,请使用<code>future.wait</code>. 这需要一个列表或 futures and returns a future of lists**:

this is ideal when the futures are independent, and they don't need to execute sequentially.

这是一个示例<code>passwordvalidator</code>类:

因为该方法名为<code>call</code>,我们可以声明一个类实例并将其用作方法:

假设我们有一个自定义小部件类,它应该<code>ondragcompleted</code>在发生特定事件时调用回调:

要调用回调,我们可以编写以下代码:

但是有一个更简单的方法(注意使用<code>?.</code>):

在 dart 中,函数是一等公民,可以作为参数传递给其他函数。

下面是一些定义匿名函数并将其分配给<code>sayhi</code>变量的代码:

然后<code>sayhi</code>传递给一个<code>welcome</code>函数,该函数接受一个<code>function</code>参数并使用它来迎接用户。

<code>string function(string)</code>是一个函数类型,它接受一个<code>string</code>参数并返回一个<code>string</code>. 因为上面的匿名函数具有相同的签名,它可以直接作为参数传递,也可以通过变量传递<code>sayhi</code>。

使用功能等运营商时,这种编码风格是常见的<code>map</code>,<code>where</code>和<code>reduce</code>。

例如,这是一个计算数字平方的简单函数:

给定一个值列表,我们可以映射:

这里我们<code>square</code>作为参数传递,因为它的签名正是 map 操作符所期望的。这意味着我们不需要用匿名函数扩展它:

当您将 ui 作为代码编写时,collection-if 和 spreads 非常有用。

但是您知道您也可以将它们与maps一起使用吗?

考虑这个例子:

这里我们声明一个<code>restaurant</code>maps,只添加<code>avgrating</code>和<code>numratings</code>键值对,如果<code>addratings</code>是<code>true</code>。因为我们要添加多个键值对,所以我们需要使用扩展运算符 ( <code>...</code>)。

假设你有map:

以下是如何编写循环以使用所有键值对运行一些代码:

通过迭代<code>entries</code>变量,您可以以空安全的方式访问所有键值对。

这比这更简洁,更不容易出错:

上面的代码<code>!</code>在读取值时需要使用断言运算符 ( ),因为 dart 不能保证给定键的值存在。

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

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

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

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

在<code>temperature</code>上面的类中,<code>celsius</code>被声明为存储变量。

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

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

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

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

在 flutter 中,我们经常使用带有函数参数的小部件。一个常见的例子是<code>listview.builder</code>:

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

注意:这两个参数是不同的 (<code>_</code>和<code>__</code>),因为它们是单独的标识符。

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

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

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

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

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

dart 中最常用的集合类型是<code>list</code>.

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

我们可以<code>set</code>在需要一组唯一值时使用 a (请注意 的使用<code>final</code>):

上面的代码生成一个警告,因为<code>深圳</code>出现了两次。如果我们尝试对<code>const</code>set执行相同的操作,则会收到错误并且我们的代码无法编译:

我们能够获得有用的api,如<code>union</code>,<code>difference</code>和<code>intersection</code>:

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

<code>try</code>并且<code>catch</code>在使用基于 future 的 api 时非常理想,如果出现问题,这些 api 可能会引发异常。

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

一些注意事项:

您可以添加多个<code>on</code>子句来处理不同类型的异常。

您可以使用回退<code>catch</code>子句来处理与上述任何类型都不匹配的所有异常。

您可以使用<code>rethrow</code>语句将当前异常向上抛出调用堆栈,同时保留堆栈跟踪。

您可以使用<code>finally</code>在<code>future</code>完成后运行一些代码,无论它是成功还是失败。

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

dart<code>future</code>类带有一些方便的工厂构造函数:<code>future.delayed</code>,<code>future.value</code>和<code>future.error</code>。

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

但有时我们想创建一个<code>future</code>立即完成的:

我们可以用<code>future.value</code>一个值来成功完成,或者<code>future.error</code>用一个错误来完成。

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

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

用于从值列表<code>stream.fromiterable</code>创建一个<code>stream</code>。

使用<code>stream.value</code>,如果你只有一个值。

用于<code>stream.empty</code>创建空流。

用于<code>stream.error</code>创建包含错误值的流。

用于<code>stream.fromfuture</code>创建仅包含一个值的流,该值将在未来完成时可用。

用于<code>stream.periodic</code>创建周期性的事件流。您可以将 a 指定<code>duration</code>为事件之间的时间间隔,并指定一个匿名函数来生成给定其在流中的索引的每个值。

在 dart 中,我们可以将同步生成器定义为一个返回 的函数<code>iterable</code>:

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

另一方面,异步生成器是一个返回 a 的函数<code>stream</code>:

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

但是如果我们愿意,我们可以使用<code>await</code>基于 future 的 api,因为这是一个异步生成器:

那么今天的分享就要和大家说再见了,我们明天见,明天将给大家继续带来flutter的精彩内容。

大家有什么疑问或者问题,都可以在留言区告诉我,如果喜欢今天的内容,欢迎大家点赞支持!