和其他编程语言一样,Dart 的操作符分为算术操作符、位操作符、布尔操作符、关系操作符等等,下文将对这些操作符进行详细讲解。
算术操作符
四则运算
用法示例:
print(1 + 2);// output: 3 加
print(1 - 2);// output: -1 减
print(1 * 2);// output: 2 乘
print(1 / 2);// output: 0.5 除
print(10 % 3);// output: 1 余
print(10 ~/ 3);// output: 3 商
自增自减
先自增再运算
main() {
int foo = 1;
var bar = ++foo;
print(foo);// output: 2
print(bar);// output: 2
}
先运算再自增
main() {
int foo = 1;
var bar = foo++;
print(foo);// output: 2
print(bar);// output: 1
}
先自减再运算
main() {
int foo = 1;
var bar = --foo;
print(foo);// output: 0
print(bar);// output: 0
}
先运算再再减
main() {
int foo = 1;
var bar = foo--;
print(foo);// output: 0
print(bar);// output: 1
}
位操作符
位操作符用于在最基本的层次上,即按内存中表示数值的位来操作数值。Dart 中所有的数值都是以 64 位进行储存的,但是位操作符并不是直接操作 64 位的值,而是先将 64 位的值转换为 32 位的整数,然后执行操作,最后再将结果转换回 64 位。
对于有符号的整数,32 位中的前 31 位用于表示整数的值。第 32 位用于表示数值的符号: 0 表示正数, 1 表示负数。这个表示符号的位叫做符号位,符号位的值决定了其他位数值的格式。例如,数值 18 的二进制表示是 00000000000000000000000000010010
,或者更简洁的 10010
,这是 5 个有效位,这 5 位本身就决定了实际的值。
和其他语言一样,Dart 的位操作符有如下 6 种:
-
&
:位与,2 个数相同位的值都为 1 时取 1 -
|
:位或,2 个数相同位的值只要有一个为 1,则取 1 -
~
:位非,1 元操作符,对数值取二进制反码,即每个位都取反。 -
^
:异或,2 个数相同位的值不同,则取 1 -
<<
:左移,将数值的所有位向左移动指定的位数。 -
>>
:右移,将数值的所有位向右移动指定的位数。
相关用法示例:
main() {
int foo = 18;
int bar = 17;
print(foo & bar);// output: 16
print(foo | bar);// output: 19
print(~foo);// output: -19
print(foo ^ bar);// output: 3
print(foo << 5);// output: 576
print(bar >> 5);// output: 0
}
布尔操作符
布尔操作符是所有编程语言中最常用的操作符,包含 &&
,||
,!
3 个操作符,相关含义我就不再赘述,需要注意的是 Dart 的 布尔操作符和 JavaScript、PHP 不同,只能对布尔值进行操作,这一点前面提到过很多次了,相关用法示例:
main() {
bool foo = true;
bool bar = false;
print(foo && bar);// output: false
print(foo || bar);// output: true
print(!foo);// output: false
print(!bar);// output: true
}
关系操作符
Dart 和 JavaScript、PHP 这种弱类型语言不同,没有隐式转换,所以没有 ===
和 !==
,并且只有 int
类型才能比较大小,其他类型只能比较是否相等。
main() {
int foo = 1;
var bar = 1;
print(foo > bar);// false
print(foo < bar);// false
print(foo == bar);// true
print(foo != bar);// false
print(foo >= bar);// true
print(foo <= bar);// true
}
赋值操作符
简单的赋值操作符由等于号 =
表示,其作用就是把右侧的值赋给左侧的变量,如下面的例子所示:
main() {
bool foo = true;
print(foo);// output: true
}
=
每个例子都在使用,已经用过很多次了,还有一些其他赋值操作符可以完成复合赋值操作,每个算术操作符都有对应的复合赋值操作符,这些操作符如下所示:
操作符 | 作用 |
---|---|
+= |
加/赋值 |
-= |
减/赋值 |
*= |
乘/赋值 |
/= |
除/赋值 |
%= |
取余/赋值 |
~/= |
取商/赋值 |
<<= |
左移/赋值 |
>>= |
右移/赋值 |
&= |
按位与/赋值 |
|= |
按位或/赋值 |
^= |
按位异或/赋值 |
一些用法示例:
main() {
int foo = 6;
int bar = 7;
int i = 66;
int j = 18;
foo += 3;
bar -= 1;
i ~/= 22;
j &= 1;
print(foo);// output: 9
print(bar);// output: 6
print(i);// output: 3
print(j);// output: 0
}
条件表达式
三元运算符::?
,条件成立执行前者,否则,执行后者。
main() {
int num1 = 666;
int num2 = 777;
var max = (num1 > num2) ? num1 : num2;
print(max);// output: 777
}
短路操作符:??
,前表达式求值若为 null
,则取后者,这和 JavaScript 中的 ||
有异曲同工之妙。
main() {
int foo;
int num = foo ?? 666;
print(num);// output: 666
}
前面提过每个算术操作符都有对应的复合赋值操作符,而短路操作符 ??
其实也有一个对应的复合赋值操作符 ??=
,它的用法如下:
main() {
int num1;
num1 ??= 666;
int num2 = 777;
num2 ??= 888;
print(num1);// output: 666
print(num2);// output: 777
}
由上面的结果可以看出 ??=
操作符的作用是:如果 ??=
前的变量为 null
,则将对该变量赋值,否则不对该变量赋值。
级联操作符
级联操作符 ..
允许对同一对象执行一系列操作。除了函数调用,还可以访问同一对象上的字段。这通常会省去创建临时变量的步骤,并允许我们编写更多的级联代码。
相关用法示例:
querySelector('#confirm') // 获取一个对象
..text = 'Confirm' // 使用它的成员
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
其他操作符
前面已经将绝大多数操作符解释完了,还剩下几个操作符:
-
()
:表示函数调用 -
[]
:指列表中指定索引处的值 -
.
:指表达式的属性;例如,foo.bar
表示从表达式foo
中选择属性bar
-
?.
:和.
用法相同,但是最左边的操作数可以为空,例如,foo?.bar
表示从表达式foo
中选择属性bar
,若foo
为空,则foo?.bar
的值就是空