先看看Dart定义了哪些运算符 多数的运算符是可以被重载的.
类型 | 操作符 |
---|---|
一元后缀符 | expr++ expr-- () [] . ?. |
一元前缀符 | -expr !expr ~expr ++expr – |
乘除 | * / % ~/ |
加减 | + - |
位移 | << >> >>> |
与运算 | & |
位异或 | ^ |
或运算 | |
关系与类型 | >= > <= < as is is! |
相等性 | == != |
逻辑与 | && |
逻辑或 | |
如果为空 | ?? |
三元运算符 | expr1 ? expr2 : expr3 |
解耦 | … |
赋值 | = *= /= += -= &= ^= |
Dart 支持常用的运算运算符,如下表所示:
运算符 | 描述 |
---|---|
+ | 加法 |
- | 减法 |
-expr | 负数 |
* | 惩罚 |
/ | 除法 |
~/ | 除法(但是返回一个整数) |
% | 取模 |
assert(2 + 3 == 5);
assert(2 - 3 == -1);
assert(2 * 3 == 6);
assert(5 / 2 == 2.5); // 结果是双浮点型
assert(5 ~/ 2 == 2); // 结果是整型
assert(5 % 2 == 1); // 余数
Dart 还支持前缀和后缀,自增和自减运算符。
运算符 | 描述 |
---|---|
++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; // a自加后赋值给b。
assert(a == b); // 1 == 1
a = 0;
b = a++; // a先赋值给b后,a自加。
assert(a != b); // 1 != 0
a = 0;
b = --a; // a自减后赋值给b。
assert(a == b); // -1 == -1
a = 0;
b = a--; // a先赋值给b后,a自减。
assert(a != b); // -1 != 0
下表列出了关系运算符及含义:
运算符 | 描述 |
---|---|
== | 是否相等 |
!= | 是否不相等 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
要测试两个对象x和y是否表示相同的事物, 使用 == 运算符。 (在极少数情况下, 要确定两个对象是否完全相同,需要使用 identical() 函数。) 下面给出 == 运算符的工作原理:
如果 x 或 y 可以 null,都为 null 时返回 true ,其中一个为 null 时返回 false。
结果为函数 x.==(y) 的返回值。 (如上所见, == 运算符执行的是第一个运算符的函数。 我们甚至可以重写很多运算符,包括 ==, 运算符的重写,参考 重写运算符。)
这里列出了每种关系运算符的示例:
assert(2 == 2);
assert(2 != 3);
assert(3 > 2);
assert(2 < 3);
assert(3 >= 3);
assert(2 <= 3);
运算符 | 描述 |
---|---|
as | 类型强转 |
is | 如果对象具有指定的类型,则为真 |
is! | 如果对象没有指定的类型,则为真 |
我们可以使用=运算符分配值。要仅在分配给变量为空时进行分配,请使用??=运算符。
例:
运算符 | 描述 |
---|---|
!obj | 反转以下表达式(将 false 更改为 true,反之亦然) |
|| | 逻辑或 |
&& | 逻辑与 |
运算符 | 描述 |
---|---|
& | 与运算 |
^ | 异或 |
~expr | 一元按位补码(0 变为 1;1 变为 0) |
<< | 左移 |
>> | 右移 |
>>> | 无符号右移 |
Dart 有两个运算符,可让您简洁地取代可能需要if-else语句的表达式:
condition ? expr1 : expr2
如果条件为真,则计算expr1(并返回其值);否则,计算并返回expr2的值。
expr1 ?? expr2
如果expr1不为 null,则返回其值;否则,计算并返回expr2的值。
当您需要基于布尔表达式分配值时,请考虑使用?and :。
var visibility = isPublic ? 'public' : 'private';
如果布尔表达式测试 null,请考虑使用??.
String playerName(String? name) => name ?? 'Guest';
级联 ( …, ?..) 允许对同一对象进行一系列操作。除了访问实例成员之外,还可以在同一对象上调用实例方法。这通常会节省创建临时变量的步骤,并允许编写更流畅的代码。
var paint = Paint()
..color = Colors.black
..strokeCap = StrokeCap.round
..strokeWidth = 5.0;
构造函数Paint()返回一个Paint对象。级联符号后面的代码对该对象进行操作,忽略任何可能返回的值。
前面的例子等价于这段代码:
var paint = Paint();
paint.color = Colors.black;
paint.strokeCap = StrokeCap.round;
paint.strokeWidth = 5.0;
如果级联操作的对象可以为空,则对第一个操作使用空短级联 ( ?..)。首先?..保证不会在该空对象上尝试任何级联操作。
querySelector('#confirm') // Get an object.
?..text = 'Confirm' // Use its members.
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'))
..scrollIntoView();
前面的代码等价于以下代码:
var button = querySelector(‘#confirm’);
button?.text = ‘Confirm’;
button?.classes.add(‘important’);
button?.onClick.listen((e) => window.alert(‘Confirmed!’));
button?.scrollIntoView();
同时也可以嵌套级联。例如:
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');
该sb.write()调用返回 void,所以并没有任何对象支持你使用级联符号