Dart语法糖

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

2019-05-02  本文已影响41人  小哥_xiaoge

一、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 支持单行注释、多行注释和 文档注释。

// 打印 ff
  print('ff');
/*
   * This is a lot of work. Consider raising chickens.

  Llama larry = new Llama();
  larry.feed();
  larry.exercise();
  larry.clean();
   */
  // 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) {
    // ...
  }
上一篇下一篇

猜你喜欢

热点阅读