运算符
Dart 定义了下表中显示的运算符 可以重载其中的许多运算符 请参考 可重载的运算符
| Description (简介) | Operator (运算符) |
|---|---|
| unary postfix | expr++ expr-- () [] . ?. |
| unary prefix | -expr !expr ~expr ++expr --expr |
| multiplicative | * / % ~/ |
| additive | + - |
| shift | << >> >>> |
| bitwise AND | & |
| bitwise XOR | ^ |
| bitwise OR | | |
| relational and type test | >= > <= < as is is! |
| equality | == != |
| logical AND | && |
| logical OR | || |
| if null | ?? |
| conditional | expr1 ? expr2 : expr3 |
| cascade | . . |
| assignment | = *= /= += -= &= ^= etc. |
警告:运算符优先级请查阅 Dart语言规范
使用运算符时即创建表达式 运算符表达式 示例:
a++a + ba = ba == bc ? a : ba is T123456
在运算符表中 每个运算符的优先级都比其后面各行中的运算符高
如 乘法运算符 % 的优先级高于相等运算符
== 其优先级高于逻辑运算符 &&
该优先级意味着以下两行代码以相同的方式执行:
// Parentheses improve readability.if ((n % i == 0) && (d % i == 0)) ...// Harder to read, but equivalent.if (n % i == 0 && d % i == 0) ...12345
算术运算符
| Operator (运算符) | Meaning (含义) |
|---|---|
| + | 加 |
| – | 减 |
| -expr | 一元减号 也称之为负号(反转表达式符号) |
| * | 乘 |
| / | 除 |
| ~/ | 取商(整数结果) |
| % | 取模(余数的整数结果) |
示例:
assert(2 + 3 == 5);assert(2 - 3 == -1);assert(2 * 3 == 6);assert(5 / 2 == 2.5); // Result is a doubleassert(5 ~/ 2 == 2); // Result is an intassert(5 % 2 == 1); // Remainderassert('5/2 = ${5 ~/ 2} r ${5 % 2}' == '5/2 = 2 r 1');12345678Dart 还支持前缀和后缀的增量和减量运算符
| Operator (运算符) | Meaning (含义) |
|---|---|
| ++var | var = var + 1 (表达式的值 = var + 1) |
| var++ | var = var + 1 (表达式的值 = var) |
| −−var | var = var – 1 (表达式的值 = var – 1) |
| var−− | var = var – 1 (表达式的值 = var) |
示例:
var a, b;a = 0;b = ++a; // Increment a before b gets its value.assert(a == b); // 1 == 1a = 0;b = a++; // Increment a AFTER b gets its value.assert(a != b); // 1 != 0a = 0;b = --a; // Decrement a before b gets its value.assert(a == b); // -1 == -1a = 0;b = a--; // Decrement a AFTER b gets its value.assert(a != b); // -1 != 01234567891011121314151617
平等与关系运算符
下表中列出了相等运算符和关系运算符的含义
| Operator (运算符) | Meaning (含义) |
|---|---|
| == | 等于 |
| != | 不等于 |
| > | 大于 |
| < | 小于 |
| >= | 大于等于 |
| <= | 小于等于 |
要测试两个对象 X 和 Y是否相等 使用 == 运算符在极少数情况下 需要知道两个对象是否是完全相同的对象 使用 identical() 函数运算符的使用方式 :
assert(2 == 2);assert(2 != 3);assert(3 > 2);assert(2 < 3);assert(3 >= 3);assert(2 <= 3);123456
类型测试运算符
as is 和 is! 运算符在运行时用来检查类型非常方便
| Operator (运算符) | Meaning (含义) |
|---|---|
| as | Typecast(也用于指定库前缀) |
| is | 如果检验对象是指定的类型 则返回 True |
| is! | 如果检验对象非指定的类型 则返回 True |
如果 obj 是由 T 的接口实现的 那么表达式obj is T则返回 True
如:obj is Object 总是返回 True
使用 as 运算符将对象转换为特定类型一般情况下 应将其用在检测对象语句的简写 例如:
if (emp is Person) {// Type checkemp.firstName = 'Bob';}1234使用 as 运算符可以缩短代码:
(emp as Person).firstName = 'Bob';1
如果 emp 为 null 或者不是 Person 则第一个示例不执行任何操作 而第二个示例则会引发异常
赋值运算符
赋值号 = 运算符 对变量进行赋值 在变量为原本为 null 的情况下赋值则需要使用 ??= 运算符
// Assign value to aa = value;// Assign value to b if b is null; otherwise, b stays the sameb ??= value;1234
复合赋值运算符 将运算与赋值结合在一起
| = | –= | /= | %= | >>= | ^= |
|---|---|---|---|---|---|
| += | *= | ~/= | <<= | &= | |= |
逻辑运算符的示例:
if (!done && (col == 0 || col == 3)) {// ...Do something...}123按位和移位运算符
| Operator (运算符) | Meaning (含义) |
|---|---|
| & | 与 |
| || | 或 |
| ^ | 异或 (同为 0 异为 1) |
| ~expr | 一元按位补码(0变为1 1变为0) |
| << | 往左位移 |
| >> | 往右位移 |
使用按位和移位运算符的示例:
final value = 0x22;final bitmask = 0x0f;assert((value & bitmask) == 0x02); // ANDassert((value & ~bitmask) == 0x20); // AND NOTassert((value | bitmask) == 0x2f); // ORassert((value ^ bitmask) == 0x2d); // XORassert((value << 4) == 0x220); // Shift leftassert((value >> 4) == 0x02); // Shift right123456789
条件表达式
Dart 有两种条件运算符 在使用 if-else 表达式时更方便:
condition ? expr1 : expr2// 如果条件为真 则结果为(返回) expr1 否则结果为 expr212
expr1 ?? expr2// 如果 expr1 非空则结果为(返回) expr1 否则结果为 expr212
如果需要基于布尔表达式来判断分配值时 使用 condition ? expr1 : expr2
var visibility = isPublic ? 'public' : 'private';1
如果布尔表达式的结果为 null 请考虑使用 expr1 ?? expr2
String playerName(String name) => name ?? 'Guest';1
前面的示例至少可以用两种其它其他方式编写 但不那么简洁:
// Slightly longer version uses ?: operator.String playerName(String name) => name != null ? name : 'Guest';// Very long version uses if-else statement.String playerName(String name) {if (name != null) {return name;} else {return 'Guest';}}1234567891011级联符号
级联(..)同一对象执行系列操作除了函数调用
访问同一对象上的字段
节省创建临时变量的步骤
编写更多流畅的代码
querySelector('#confirm') // Get an object...text = 'Confirm' // Use its members...classes.add('important')..onClick.listen((e) => window.alert('Confirmed!'));1234第一个方法调用 querySelector() 返回选择器的对象 遵循级联表示法的代码在此选择器对象上运行 而忽略了可能返回的其它后续值
等效于:
var button = querySelector('#confirm');button.text = 'Confirm';button.classes.add('important');button.onClick.listen((e) => window.alert('Confirmed!'));1234也可以嵌套级联 例如:
final addressBook = (AddressBookBuilder()..name = 'jenny'..email = 'jenny@example.com'..phone = (PhoneNumberBuilder()..number = '415-555-0100'..label = 'home').build()).build();12345678
在返回实际对象的函数上构造级联 例如以下的错误代码:
var sb = StringBuffer();sb.write('foo')..write('bar'); // Error: method 'write' isn't defined for 'void'.123因为不能在 void 上构建级联 所以sb.write() 调用返回 void 在此处构建级联所以错误
提示: 严格来说 级联的 “双点” 符号不是运算符它只是Dart语法的一部分
Dart支持.操作符调用对象的方法
但 Dart 另外增加了一种级联运算符.. 用两个点表示
级联运算符可在同一个对象上连续调用多个方法及访问成员变量
..可避免创建临时变量 代码更流畅
如类Person有三个方法 setName、setAge、save 可调用
new Person()..setName("Bob")..setAge(20)..save();
使用级联运算符调用方法
无需该方法返回对象本身即可连续的流式的调用该对象的其他方法
条件成员访问符
Java空指针错误
因此在方法调用前需要进行对象的非空判断
判断语句使代码冗长 可读性差
Dart 发明了新的运算符用于处理此类情况
条件成员访问符?.
和.类似 但运算符左边的对象不能为null
否则返回null
若对象不为null 则返回对象本身
// list1默认值为null
List list1;
print(list1?.length); // null
List list2 = [];
print(list2?.length); // 0
其它运算符
在其他示例中 我们已经认识了大多数的运算符 接下来我们展示剩下的一些运算符:
| Operator (运算符) | Name(名称) | Meaning (含义) |
|---|---|---|
| () | Function application | 代表一个函数调用 |
| [] | List access | 引用列表中指定索引处的值 |
| . | Member access | 引用表达式的属性 例如 foo.bar 意思是从表达式 foo 中选择其属性 bar |
| ?. | Conditional member access | 类似于 ., 但是最左边的操作数可以为 null; 例如 foo?.bar 意思是从表达式 foo 中选择属性bar 除非 foo 为 null(在这种情况下 foo?.bar 的值为 null) |
有关 (.,|?.|..) 的更多信息 请参见 Classes

尊贵的董事大人
英文标题不为空时 视为本栏投稿
需要关键字 描述 英文标题