善用 Dart 运算符编写简洁无错的代码

此文是致力于帮助你更好地理解并高效使用 Dart 语言系列文集的第一篇。

Dart(2.0+) 和 Flutter 都是相对较新的技术,每天都有大量的人加入开发者社区,他们参考的很多示例代码仍在照搬其他语言中的代码模式,而未使用 Dart 提供的完整运算符集。

1、 ?:(三目运算符)

三目运算符已经存在于许多语言中,它允许将 if-else 语句中两条可能的执行路径改写为更简洁的形式。

比如以下代码:

可以写成:

三元运算符的结构如下所示:

condition ? (statement if true) : (statement if false);

如果涉及到返回值,return只需要加在开头,而不是在子语句中:

return condition ? (statement if true) : (statement if false);

而不是

condition ? return (statement if true) : return (statement if false);

2、 ??

?? 是 null 检查符。在上例中,如果 person.name 为 null,则 name 被赋值为 "John Doe"。这大大简化了代码,减少了先检查 name 是否为空,再决定如何赋值的逻辑(如下图的代码对比)。

?? 运算符无需大量检查代码,能更加容易地处理意外的 null 值。

3、?.

设想一个叫 Point 的类,它有 x 和 y 成员:

classPoint {
int x;
int y;
Point(this.x, this.y);
}

如果我们有一个未初始化的 Point 对象,并且试图访问内部成员,它不会返回 null,而是直接抛出一个错误。

比如:


Point point;

print(point.x);

将抛出:

Unhandled exception:
NoSuchMethodError: The getter 'x'was called on null.
Receiver: null
Tried calling: x

相反,如果它只返回 null,我们可以就很容易地处理和解决未初始化的问题。

同样,简单的解决方案是使用 if-else:

这看起来不错,但很容易遇到限制。以我们解析 JSON 为例,它可能有很多层嵌套的数据。比如:

pages[0].contributors[0].authorDetails.basicInfo.firstName

程序中任何错误都可能导致这个调用链中某个部分为 null。例如说,authorDetails 可能根本没有 basicInfo 字段。

在这些情况下,判空检查是一场噩梦,只要这些字段中的一个字段为空(firstName 除外,因为它是最后一个字段),则整个调用都会失败。

那我们该怎么办?没有简单的 if-else 或三目运算解决方案。而且在一个完美的系统里,这个错误根本不应该存在,但我们并不总会有完美的系统和 API。此时,?. 运算符派上用场了。

这个运算符大致表述为:“如果对象不为 null,则访问内部字段,否则返回 null。”

因此,即使我们前面的 point.x 示例也会抛出 null 而不是错误。这使我们的工作变得更加容易,并且可以简单地使用上一个运算符来处理 null 错误。

这里如果 point 未初始化,访问 x 将返回 null 而不是抛出错误。然后这个 null 被 null 检查运算符(??)捕获,该运算符将 0 赋值给变量 x。

类似地,我们可以将前面的示例修改为:

pages[0]?.contributors[0]?.authorDetails?.basicInfo?.firstName ?? "N/A";

现在,如果表达式任意部分为 null,则将返回 "N/A"。

4、??=

??= 可简单的理解为:“如果表达式左侧为空,则执行赋值”。即只有当变量为 null 时才会被赋值。

可以避免给变量做不必要的重新赋值。

5、=>

=> 在 Dart 中被称为胖箭头 (fat arrow) 符号。它有两种不同的用途,两者都与定义函数有关。

首先将其作为返回某物的简写,=> x 表示 { return x;}

此外该运算符也适用于单个语句,即使不返回任何内容。

请注意,如果返回类型是 void,则即使是 => s 也不会返回任何东西。

6、..(级联符号)

级联表示法是一种修改对象属性的简单方式,通常用于在创建对象而不是获取该对象的引用时逐个修改其属性。

我们要举的第一个例子还是之前的 Point 类。假设我们首先需要初始化类,然后设置x和y属性。你可能会想到这么做:

Point p = Point();
p.x= 3;
p.y= 6;

级联表示法为我们提供了一种更简单的方法,无需再次使用对象来设置属性。

需要注意的,如果我们只是使用 . 运算符,第一行不会返回一个 Point 对象。

级联符号的主要作用是:

1. 将 Point 对象创建为默认值;

2. 通过级联操作更改任何受影响的属性;

3. 返回原始对象(此处为 Point 实例);

这在需要设置大量属性时非常有用,例如在 Builder 模式中。Dart 文档中有个很好的例子:

7、~/

Dart 也有几个用于加速算术运算的运算符。~/ 运算符返回除法计算结果的整数部分。

以上介绍的这些运算符简化了代码并减少了 Bug 的发生。

8、追加:展开运算符 ...(尚未发布)

... 是一个还在讨论中的运算符,用作 Dart 中集合 (collections) 的展开运算符。

List 可以很方便地被展开:

这段代码直接将 demoList 的元素展开添加至列表中,而不是将其作为 List 对象添加。


来源:https://medium.com/flutter-community/simple-and-bug-free-code-with-dart-operators-2e81211cecfe
作者:Deven Joshi
编译:码王爷

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容

  • 运算符是处理数据的基本方法,用来从现有的值得到新的值。JavaScript 提供了多种运算符,本章逐一介绍这些运算...
    徵羽kid阅读 667评论 0 0
  • dart定义了下表所示的运算符。你可以重写许多这些运算符。 描述运算符一元后缀expr++ expr-- () [...
    你需要一台永动机阅读 51,248评论 3 42
  • 概要 64学时 3.5学分 章节安排 电子商务网站概况 HTML5+CSS3 JavaScript Node 电子...
    阿啊阿吖丁阅读 9,142评论 0 3
  • 王小波认为,1.凡是人都热爱智慧。2.凡是人都热爱异性。3.凡是人都喜欢有趣。 ——没有智慧、性爱而且没意思的生活...
    如玉2016阅读 432评论 0 0
  • 文:一禾 原文:你是我的老朋友 回忆总是在年少 影子伴着夕阳在树下摇 你总爱对着阳光笑 棒棒糖 漫画圈 漫无目的地...
    如常杂货阅读 338评论 0 1