(四)Dart操作符、代码注释

一、Operators(操作符)

注:expr为表达式,操作符的优先级在下表中自上而下的顺序由高到低

描述 操作符
一元后缀 expr++ expr-- () [] . ?.
一元前缀 -expr !expr ~expr ++expr --expr
乘法类型 * / % ~/
加法类型 + -
移动位运算 << >>
位运算 &
异或位运算 ^
位运算 |
关系和类型测试 >= > <= < as is is!
等式 == !=
逻辑与 &&
逻辑或 ||
空值判断 ??
条件 expr1 ? expr2 : expr3
级联 ..
赋值 = *= /= ~/= %= += -= <<= >>= &= ^= |= ??=

1.1. Arithmetic operators(算术操作符)

操作符 解释
+ 加号
- 减号
-expr 负号
* 乘号
/ 除号
~/ 除号,但是返回值为整数
% 取模
    var a = 20 ~/ 5;
    var b = 20 ~/ 3;
    var c = 20 ~/ 3.0;

    /*
      Dart是强语法类型,报错:A value of type 'double'
      cant't be assigned to a variable of type 'int'.
     */
    int d = 20 / 3;

    /*
      可以调用toInt()强制类型转换,但是不建议使用,编译器会提示:
      The operator x ~/ y is more efficient than (x / y).toInt().
     */
    int e = (20 / 3).toInt();

    print(a); // 4
    print(b); // 6
    print(c); // 6
    print(e); // 6

Dart 还支持递增、递减前缀 和后缀操作:

操作符 解释
++var var = var + 1 (expression value is var + 1)
var++ var = var + 1 (expression value is var)
--var var = var – 1 (expression value is var – 1)
var-- var = var – 1 (expression value is var)

1.2.Equality and relational operators(相等相关的操作符)

注:要测试两个对象代表的是否为同样的内容,使用 == 操作符。(在某些情况下,你需要知道两个对象是否是同一个对象, 使用identical() 方法。)

操作符 解释
== 相等
!= 不等
> 大于
< 小于
>= 大于等于
<= 小于等于
     List list1 = List();
     List list2 = List();
     Map map = Map();
     
     Object a = List();
     Object b = List();
     
     int c = 2;
     int d = 6;
     int h = 2;

     print(identical(list1, map)); // false
     print(identical(list1, list2)); // false
     print(identical(c, d)); // false
     print(identical(a, b)); // false

     print(identical(c, h)); // true
     // 为什么 c和h是同一个对象?因为HashCode相同!
     print(identityHashCode(c)); // 2
     print(identityHashCode(h)); // 2

1.3. Type test operators(类型判定操作符)

asis、和is! 操作符是在运行时判定对象 类型的操作符:

操作符 解释
as 类型转换
is 如果对象是指定的类型返回 True
is! 如果对象是指定的类型返回 False

只有当 obj 实现了 T 的接口, obj is T 才是 true。例如 obj is Object 总是 true

使用 as 操作符把对象转换为特定的类型。 一般情况下,你可以把它当做用 is 判定类型然后调用所判定对象的函数的缩写形式。例如下面的示例:

/ *
注意: 下面这两个代码效果是有区别的。如果 emp 是 null 或者不是 Person 类型, 
则使用 is 则不会执行条件里面的代码,而使用 as 则会抛出一个异常。
*/
if (emp is Person) {  // 类型检查
  emp.firstName = 'Bob';
}

// 使用 as 操作符可以简化上面的代码:
(emp as Person).firstName = 'Bob';

1.4. Assignment operators(赋值操作符)

使用= 操作符来赋值。 但是还有一个 ??= 操作符用来指定 值为 null 的变量的值。

操作符 操作符 操作符 操作符 操作符 操作符
= –= /= %= >>= ^=
+= *= ~/= <<= &= |=

下面是复合赋值操作符工作原理解释:

复合赋值操作符 相等的表达式
对于 操作符 op: a op= b a = a op b
示例: a += b a = a + b
    int a = 7; // 给 a 变量赋值
    /*
      如果 b 是 null,则赋值给 b;如果不是 null,则 b 的值保持不变
     */
    int b = 1;
    b ??= 9; 
    
    // 使用 ??= 前,变量c一定要先声明或者声明且赋值的,否则编译器报错
    int c ??= 9;

1.5.Logical operators(逻辑操作符)

操作符 解释
!expr 对表达式结果取反(true 变为 false ,false 变为 true)
|| 逻辑或
&& 逻辑与

1.6.Bitwise and shift operators(位和移位操作符)

操作符 解释
& AND(与)
| OR(或)
^ XOR(异或)
~expr Unary bitwise complement (0s become 1s; 1s become 0s)(一元位补码( 0s变为1s;1s变为0s ))
<< Shift left(左移)
>> Shift right(右移)
final value = 0x22;
final bitmask = 0x0f;

assert((value & bitmask)  == 0x02);  // 与
assert((value & ~bitmask) == 0x20);  // 与非
assert((value | bitmask)  == 0x2f);  // 或
assert((value ^ bitmask)  == 0x2d);  // 异或
assert((value << 4)       == 0x220); // 左移
assert((value >> 4)       == 0x02);  // 右移

1.7.Conditional expressions(条件表达式)

Dart有两个运算符,可让您简明地评估可能需要if-else语句的表达式:
condition ? expr1 : expr2
如果条件为真,返回expr1,否则返回expr2
expr1 ?? expr2
如果expr1为非空,则返回其值;否则,计算并返回expr2的值。

  • 如果你需要根据布尔表达式赋值时,考虑使用?:
var isHidden = (3 > 2) ? true : false;
  • 如果布尔表达式测试为空,考虑使用??
String studentName(String name) => msg ?? 'Tom';

// 非常长的使用if - else语句的版本
String studentName(String name) {
  if (name != null) {
    return name;
  } else {
    return 'Tom';
  }

1.8.Cascade notation (..)(级联操作符)

级联操作符 (..) 可以在同一个对象上连续调用多个函数以及访问成员变量。 使用级联操作符可以避免创建临时变量,并且写出来的代码看起来更加流畅:

querySelector('#confirm') // 获取一个对象
  ..text = 'Confirm' // 使用它的成员
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'));

第一个方法 querySelector() 返回了一个 selector 对象。 后面的级联操作符都是调用这个对象的成员, 并忽略每个操作所返回的值。

上面的代码和下面的代码功能一样:

var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));

级联调用也可以嵌套:

final addressBook = (AddressBookBuilder()
      ..name = 'jenny'
      ..email = 'jenny@example.com'
      ..phone = (PhoneNumberBuilder()
            ..number = '415-555-0100'
            ..label = 'home')
          .build())
    .build();

无法在 返回值为void 上使用级联操作符:

var sb = StringBuffer();
// sb.write() 函数返回一个 void, 无法在 void 上使用级联操作符。
sb.write('foo')
  ..write('bar'); // 错误:没有为“void”定义的方法“write”。

注意: 严格来说, 两个点的级联语法不是一个操作符。 只是一个 Dart 特殊语法。

1.9.Other operators(其他操作符)

操作符 名称 含义
() 使用方法 代表调用一个方法
[] 访问List 访问List 中特定位置的元素
. 访问 Member 访问元素,例如 foo.bar 代表访问 foobar 成员
?. 条件成员访问 . 类似,但是左边的操作对象可以为 null,例如 foo?.bar 如果foonull 则返回 null,否则返回 bar 成员
    var str1 = "hello world";
    var str2 = null;
    print(str1?.length); // 11
    print(str2?.length); // null,此语法类似swift语言中的Optional(?.)
    print(str2.length); // 报错

二、代码注释

Dart 支持单行注释、多行注释和 文档注释。

  • 单行注释以 // 开始。//后面的一行内容 为 Dart 代码注释。
// 打印 ff
  print('ff');
  • 多行注释以 /* 开始, */ 结尾。 多行注释 可以 嵌套。
/*
   * This is a lot of work. Consider raising chickens.

  Llama larry = new Llama();
  larry.feed();
  larry.exercise();
  larry.clean();
   */
  • TODO注释
  // TODO: refactor into an AbstractLlamaGreetingFactory?
  print('Welcome to my Llama farm!');
  • 文档注释

文档注释可以使用 /// 开始, 也可以使用 /** 开始 并以 */结束。
在文档注释内, Dart 编译器忽略除了[]以外的内容。 使用[]引用 classesmethodsfieldstop-level variablesfunctions、 和 parameters[]里面的名字使用 当前注释出现地方的语法范围查找对应的成员(在简书markdown中,[]中的内容无法高亮显示和点击查询跳转,有些遗憾,但在例如:WebStorm、装有支持Dart IDE的插件开发工具中可以体现)。

class Food {
  
}

class Activity {
  
}

/// A domesticated South American camelid (Lama glama).
///
/// Andean cultures have used llamas as meat and pack
/// animals since pre-Hispanic times.
class Llama {
  String name;

  /// Feeds your llama [Food].
  ///
  /// The typical llama eats one bale of hay per week.
  void feed(Food food) {
    // ...
  }

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

推荐阅读更多精彩内容