运算符
先看看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 = 'jenny@example.com'
..phone = (PhoneNumberBuilder()
..number = '415-555-0100'
..label = 'home')
.build())
.build();
小心在返回实际对象的函数上构建你的级联。例如,以下代码失败:
var sb = StringBuffer();
sb.write('foo')
..write('bar');
该sb.write()调用返回 void,所以并没有任何对象支持你使用级联符号