关于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 = 'jenny@example.com'
..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。