操作符
计算机程序的表达式由操作符和操作数构成。如1+2
这个表达式中,+
是操作符,数字1
和2
是操作数。如果表达式中只有一个操作数,它便是一元表达式;如果有两个操作数,它便是二元表达式;类似地还有三元表达式。一元表达式中的操作符为一元操作符。
Dart提供了非常丰富的操作符,且支持为类(class,第4-5章内容)定义操作符。
在算数表达式中(例如 2 + 3 × 5
),乘除法的优先级高于加减法,因此优先计算乘除法( 3 × 5
),但可以通过圆括号来改变求值顺序(例如 (2 + 3) × 5)
。操作符的优先级,与算术中加减乘除的优先级类似。
算术操作符
操作符 | 含义 | 示例 |
---|---|---|
+ | 加 | 1 + 2 //3 |
- | 减 | 4 - 3 //1 |
- expr | 符号取反 | -x |
* | 乘 | 3 * 5 //15 |
/ | 除,结果是一个浮点数 | 7 / 2 //3.5 |
~/ | 整除,除法的整数部分,结果是一个整数 | 7 ~/ 2 //3 |
% | 模,除法的余数部分,结果是一个整数或浮点数 | 7 % 2 //1 |
Dart支持自增(++
)与自减(--
)一元操作符。表达式x++
相当于x = x+1
,x--
相当于x = x-1
。 这两个操作符位于操作数之前或之后均可,但有区别。
// ch0105_1.dart
void main() {
var x = 3, y = 3;
print('${x++} $x'); // Output: 3 4
print('${++y} $y'); // Output: 4 4
}
表达式x++
的值为x
,先返回x
,再将x
自增1;而表达式++x
的值为x+1
,也就是先将x
自增1,再返回x
。
我们用同样的方式去理解x--
与--x
。
关系操作符
关系操作符用于布尔表达式(其结果为true
或false
)。
操作符 | 含义 | 示例 |
---|---|---|
== | 等于 | 5 == 5 |
!= | 不等于 | 6 != 7 |
> | 大于 | 8 > 7 |
< | 小于 | 6 < 9 |
>= | 大于等于 | 4 >= 3 |
<= | 小于等于 | 3 <= 4 |
关于==
操作符:
- 如果
x
或y
为null
,则只有当它们都是null
,x==y
才返回true
;如果只有一个为null
,则x==y
返回false
。 x == y
本质上是调用x
的==
操作符方法(以y
作为参数),然后返回其结果, 类似于x.equals(y)
。- 极少情况下,你需要知道
x
和y
是否引用了同一个对象,使用identical(x,y)
。
NOTE: 方法、对象的概念将在第4章介绍。
类型测试操作符
as
、is
和 is!
操作符用于在运行时检查类型。
操作符 | 含义 | 示例 |
---|---|---|
as | 类型转换(该符号也用于import 语句中给包取别名) | obj as String |
is | 如果对象具有指定类型返回true | obj is double |
is! | 如果对象不具有指定类型返回true | obj is! num |
赋值操作符
首先来看 =
和 ??=
这两个赋值操作符。
操作符 | 含义 | 示例 |
---|---|---|
= | 赋值 | x = 123; |
??= | 仅当变量为null 才对其赋值 | x ??= 234; |
复合赋值操作符组合了一个操作和赋值,以 +=
为例, x += y
就等价于 x = x + y
。假设 op
是一个操作符,那么 a op= b
等价于 a = a op b
。以下是复合赋值操作符:
*= | %= | >>>= | ^= |
+= | /= | <<= | &= |
|= | -= | ~/= | >>= |
逻辑操作符
您使用逻辑运算符反转或组合布尔表达式。
操作符 | 含义 | 示例 |
---|---|---|
! expr | 逻辑非,逻辑取反 | !x |
|| | 逻辑或(OR) | x == 3 || x ==4 |
&& | 逻辑与(AND) | x >=1 && y < 6 |
下面是一个稍微复杂的例子:
if (ok && (x < 5 || y > 6)) {
print('good');
}
位操作符
Dart可以对数字的每一位(bit)进行操作。
操作符 | 含义 | 示例 |
---|---|---|
& | 与(AND) | 1 & 2 //0 |
| | 或(OR) | 1 | 2 //3 |
^ | 异或(XOR) | 2 ^ 3 //1 |
~ expr | 按位补码(0变为1,1变为0) | ~1 //-2 |
<< | 左移位 | 1 << 10 //1024 |
>> | 右移位 | 1024 >> 9 //2 |
>>> | 无符号右移 | -1 >>> 61 //7 |
条件表达式
先来看下面的代码片段:
int n;
if (x < 3) {
n = 3;
} else {
n = x;
}
上面计算n
的代码,用条件表达式就简化为:
var n = x < 3 ? 3 : x;
条件表达式 condition ? expr1 : expr2
,有 ?
和:
2个操作符,?
之前为一个表示条件的布尔表达式condition
;如果condition
的值为true
,该表达式的值就取expr1
的值,否则取 expr2
的值。
级联符号
Dart的级联符号(..
和 ?..
)用于对同一个对象进行一系列操作。下面的代码片段:
var sb = StringBuffer();
sb.write('Hello ');
sb.write('Dart');
sb.write('!');
print(sb);
用级联符号就简化为:
print(
StringBuffer()
..write('Hello ')
..write('Dart')
..write('!'),
);
?..
与 ..
类似,只不过用于nullable对象的第一个操作。
sb2
?..write('Hello ')
..write('Dart')
..write('!');
上面代码中的sb2
如果是null
,就不会执行任何的级联操作。
其他操作符
下面的操作符已在前面章节介绍过,不再赘述。
操作符 | 含义 | 示例 |
---|---|---|
() | 函数调用 | doIt() |
[] | 下标访问 | todoList[0] |
?[] | 有条件下标访问 | fruits?[0] |
. | 成员访问 | point.x |
?. | 有条件成员访问 | point?.x |
! | 非空断言 | point! |
... | 展开一个集合(collection),插入另一个集合(collection) | ...myList |
...? | 与... 类似,适用于nullable对象 | ....?anotherList |
操作符优先级
下表中的操作符按优先级从高到低排依次列,第一行中的优先级最高,第二行次之,以此类推; 同一行里的操作符具有相同的优先级。
描述 | 操作符 |
---|---|
一元后缀 | expr ++ expr -- () [] ?[] . ?. ! |
一元前缀 | - expr ! expr ~ expr ++ expr -- expr await expr |
乘除 | * / % ~/ |
加减 | + - |
移位 | << >> >>> |
位与 AND | & |
位异或 XOR | ^ |
位或 OR | | |
关系及类型测试 | >= > <= < as is is! |
相等 | == != |
逻辑与 AND | && |
逻辑或 OR | || |
if-null | ?? |
条件 | expr1 ? expr2 : expr3 |
级联 | .. ?.. |
赋值 | = *= /= += -= &= ^= 等 |
展开 | ... ...? |