Dart的操作符有很多,比如加减剩除,位移。在这里我们不讨论简单的操作符,只列出来简单说明一下,说一些只在Dart中出现的而其它语言没有的或者比较特别的操作符

后缀表达式	expr++    expr--    ()    []    .    ?.
前缀表达式	-expr    !expr    ~expr    ++expr    --expr   
剩除余数	*    /    %  ~/
加减	+    -
位移	<<    >>    >>>
按位AND	&
按位XOR	^
按位OR	|
比较 	>=    >    <=    <    
类型测试 as    is    is!
等与不等	==    !=   
逻辑AND	&&
逻辑OR	||
如果是null	??
三元表达式	expr1 ? expr2 : expr3
级联	..
赋值	=    *=    /=   +=   -=   &=   ^=   etc.

==相等

通常Dart实现 == 是通过比较对象的hash来实现的,如果两个对象拥有相同的hash,则这两个对象相等,这也是 == 操作符的默认行为

Dart == 操作符遵守间接等的数学规则,比如a=b,b=c那么a也等于c,下面是一些简单示例

assert(2 == 2);
assert(2 != 3);
assert(3 > 2);
assert(2 < 3);
assert(3 >= 3);
assert(2 <= 3);

如需要比较两个对象是否引用的同一个实例则使用identical()函数替代 == ,这意味两个对象的hash是一样的

external bool identical(Object a, Object b);

如果要比较同一个类的两个“相似”实例,这会返回与你期望不一致的行为,比如下面的代码

import 'dart:core';

class Person {
  String name;
  Person(this.name);
}

main(List<String> args) {
  Person bob = Person('bob');
  bob = Person('bob');
  print(bob == Person('bob')); // false
}

上面的代码中,一般情况我们会认为是相等,但在Dart中这将会返回的是false。这是因为bob对象的hash和后面实例化的Person('bob')生成hash不一致而导致Dart认为这是不相等的

既然这是默认行为,那么意味我们可以改变这种默认行为,让上面的示例中被Dart识别为相等的,这可以通过重写对象==操作符和hash来实现

class Person {
  final String name;

  const Person(this.name);

  @override
  bool operator ==(Object other) =>
    identical(this, other) ||
    other is Person &&
    runtimeType == other.runtimeType &&
    name == other.name;

  @override
  int get hashCode => name.hashCode;
}

类型测试

as,is,is!

as	转换为指定的类型
is	对象是否是指定的类型
is!	与is相反
if (emp is Person) {
  // 类型检查
  emp.firstName = 'Bob';
}
(emp as Person).firstName = 'Bob';

如果变量emp是空,第一示例是可以正常工作的,第二个示例则会抛出一个错误,因为as是会将类型转换之后再判断,dart不能将null转换为其它类型

级联

级联操作符..允许你连续在一个对象上执行操作,除了调用函数之外还可以访问对象属性,这可可以让你少写几个临时变量

querySelector('#confirm') // 取得对象.
  ..text = 'Confirm' // 访问对象属性.
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'));

没有级联操作符的写法,将会变得繁琐且会多出很多临时变量

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();

在使用级联操作符时需要注意函数的返回值,如果返回的不是对象本身,这可能会导致出错

var sb = StringBuffer();
sb.write('foo') // 返回 void
  ..write('bar'); // Error: method 'write' isn't defined fo 'void'.

严格来说,级联的..符号不是运算符。它只是Dart语法的一部分。