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语法的一部分。