关于Dart的运算符,跟其他编程语言类似,就不一一记录了,这里只介绍一下需要注意的特殊使用方式。
==判断运算符
要判断两个对象 x 和 y 是否表示相同的事物使用 ==
即可。(在极少数情况下,可能需要使用 identical() 函数来确定两个对象是否完全相同。)。下面是 ==
运算符的一些规则:
-
x==y
的原型就是x.==(y)
,也就是说==
其实是x
中的一个方法。 - 假设有变量
x
和y
,且x
和y
至少有一个为null
,则当且仅当x
和y
均为null
时x == y
才会返回true
,否则只有一个为null
则返回false
。 -
x.==(y)
将会返回值,这里不管有没有y
,即y
是可选的。也就是说==
其实是x
中的一个方法,并且可以被重写。详情请查阅重写运算符。
类型判断运算符
as、is、is! 运算符是在运行时
判断对象类型的运算符。
Operator:
as |
类型转换(也用作指定类前缀)) |
---|---|
is |
如果对象是指定类型则返回 true |
is! |
如果对象是指定类型则返回 false |
当且仅当 obj
实现了T
的接口,obj is T
才是true
。例如 obj is Object
总为 true
,因为所有类都是 Object 的子类。
使用 as
操作符可以把对象转换为特定的类型。一般情况下可以将其当做 is 判定类型后调用所判定对象的函数的缩写形式。假设有如下代码:
if (emp is Person) {
// 类型检查
emp.firstName = 'Bob';
}
你可以使用 as 运算符进行缩写:
(emp as Person).firstName = 'Bob';
备忘:
上述两种方式是有区别的:如果 emp 为 null 或者不为 Person 类型,则第一种方式最多只是不执行条件内代码,但是第二种方式则会抛出异常。
??= 赋值运算符
可以使用 =
来赋值,同时也可以使用 ??=
来为值为 null
的变量赋值。
// 将 value 赋值给 a (Assign value to a)
a = value;
// 当且仅当 b 为 null 时才赋值
b ??= value;
备忘:
??=
是当且仅当 变量为 为 null 时才赋值。
expr1 ?? expr2条件表达式
表达式 1 ?? 表达式 2
:如果表达式 1
为非 null
则返回其值,否则执行表达式 2
并返回其值。
如果赋值是根据布尔表达式则考虑使用 ?::
var visibility = isPublic ? 'public' : 'private';
如果赋值是根据判定是否为 null 则考虑使用 ??:
String playerName(String name) => name ?? 'Guest';
上述示例还可以写成至少下面两种不同的形式,只是不够简洁:
// 相对使用 ?: 运算符来说稍微长了点。(Slightly longer version uses ?: operator).
String playerName(String name) => name != null ? name : 'Guest';
// 如果使用 if-else 则更长。
String playerName(String name) {
if (name != null) {
return name;
} else {
return 'Guest';
}
}
备忘:
这个表达式用来必须返回一个非空值的场景,后面的值可以相当于一个默认值作为兜底。
级联运算符(..)
级联运算符 (..)
可以让你在同一个对象上连续调用多个对象的变量或方法。
比如下面的代码:
querySelector('#confirm') // 获取对象 (Get an object).
..text = 'Confirm' // 使用对象的成员 (Use its members).
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
第一个方法 querySelector 返回了一个 Selector 对象,后面的级联操作符都是调用这个 Selector 对象的成员并忽略每个操作的返回值。
上面的代码相当于:
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
备忘:
第一个..
前的对象就是后面能被重复调用的对象,这个功能非常强大,相当于自动集成builder模式。
级联运算符可以嵌套,例如:
final addressBook = (AddressBookBuilder()
..name = 'jenny'
..email = '[email protected]'
..phone = (PhoneNumberBuilder()
..number = '415-555-0100'
..label = 'home')
.build())
.build();
在返回对象的函数中谨慎使用级联操作符。例如,下面的代码是错误的:
var sb = StringBuffer();
sb.write('foo')
..write('bar'); // 出错:void 对象中没有方法 write (Error: method 'write' isn't defined for 'void').
上述代码中的 sb.write() 方法返回的是 void,返回值为 void 的方法则不能使用级联运算符。
"严格来说 .. 级联操作并非一个运算符而是 Dart 的特殊语法。"
?.条件返回符
与普通的访问符类似,但是左边的操作对象不能为 null,例如 foo?.bar,如果 foo 为 null 则返回 null ,否则返回 bar。