Dart 运算符
最后修改日期:2025 年 6 月 4 日
本教程将探讨 Dart 运算符,演示它们如何用于创建表达式来处理数据。
运算符 是一个符号,用于触发对其运算对象(operand)的特定操作。运算符在编程中模仿数学运算来操作数据。运算对象 是运算符的输入,通常是值或变量。
表达式结合了运算对象和运算符,运算符定义了要执行的操作。求值顺序由运算符的优先级 和结合性 决定,以确保结果可预测。
运算符根据其运算对象的数量进行分类。一元运算符 使用一个运算对象,而二元运算符 使用两个。有些运算符(如 +)是重载 的,可以根据上下文执行不同的任务(例如,对数字求和或连接字符串)。
Dart 负号运算符
负号运算符 - 用于否定一个值,反转其符号。
void main() {
int a = 1;
print(-a);
print(-(-a));
}
此示例展示了负号运算符如何否定一个值,然后将其值反转回原始符号。
$ dart main.dart -1 1
Dart 赋值运算符
赋值运算符 = 将一个值存储到变量中。与数学中的 = 表示相等性不同,在编程中,它将右侧的值赋给左侧的变量。
int x = 1;
这会将值 1 赋给变量 x。
x = x + 1;
这会将 x 增加 1,使得 x 等于 2。此类表达式在编程中是有效的,但在数学中则无效。
3 = x;
这是无效的,因为像 3 这样的字面量不能被赋值,这会导致语法错误。
Dart 的空感知赋值运算符 ??= 仅当变量为 null 时才为其赋值,从而确保安全初始化。
void main() {
int? x;
x ??= 6;
print(x);
x ??= 3;
print(x);
}
由于 x 最初为 null,因此将其赋值为 6。第二次赋值被忽略,因为 x 不再是 null。
$ dart main.dart 6 6
Dart 递增和递减运算符
递增(++)和递减(--)运算符在变量上加 1 或减 1,提供了一种简洁的更新值的方法。
void main() {
var x = 6;
x++;
x++;
print(x);
x--;
print(x);
}
此示例将 x 从 6 递增两次到 8,然后将其递减到 7,演示了这两种运算符。
$ dart main.dart 8 7
这些运算符可以是前缀或后缀,这会影响值相对于其使用的时间点进行更新,这可能导致行为上的细微差别。
void main() {
var r1 = increase(3);
print(r1);
var r2 = increase2(3);
print(r2);
}
int increase(int x) {
return ++x;
}
int increase2(int x) {
return x++;
}
前缀 ++x 在返回之前递增,得到 4。后缀 x++ 在递增之前返回原始值,得到 3。
$ dart main.dart 4 3
Dart 复合赋值运算符
复合赋值运算符将运算与赋值结合起来,为常见的更新(如加法或乘法)提供了一种简写方式。
a = a + 3; a += 3;
两个表达式都将 3 加到 a 上,其中 += 是简写形式。其他复合运算符包括 -=、*=、/=、~/=、%=、&=、|=、^=、<<= 和 >>=。
void main() {
var a = 1;
a = a + 1;
print(a);
a += 5;
print(a);
a *= 3;
print(a);
}
此示例显示了标准加法,然后是复合加法和乘法,最终 a 更新为 2、7 和 21。
$ dart main.dart 2 7 21
Dart 算术运算符
算术运算符对数字运算对象执行数学运算,包括加法、减法、乘法和除法。
| 符号 | 名称 |
|---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
~/ | 整数除法 |
% | 余数 |
上表列出了 Dart 中的算术运算符
void main() {
var a = 10;
var b = 11;
var c = 12;
var add = a + b + c;
var sb = c - a;
var mult = a * b;
var div = c / 3;
var rem = c % a;
print(add);
print(sb);
print(mult);
print(div);
print(rem);
}
此示例演示了加法、减法、乘法、除法和取余运算,其中 % 计算模(例如,12 % 10 = 2)。
$ dart main.dart 33 2 110 4.0 2
/ 运算符返回一个 double,而 ~/ 返回一个整数,区分了浮点除法和整数除法。
void main() {
var c = 5 / 2;
print(c);
var d = 5 ~/ 2;
print(d);
}
对于 5 除以 2,此示例显示 / 返回 2.5 (double),而 ~/ 返回 2 (integer)。
$ dart main.dart 2.5 2
Dart 布尔运算符
布尔运算符(也称为逻辑运算符)用于操作布尔值以控制程序流程,通常在条件语句中使用。
| 符号 | 名称 |
|---|---|
&& | 逻辑与 |
|| | 逻辑或 |
! | 否定 |
上表列出了 Dart 中的布尔运算符。
void main() {
var x = 3;
var y = 8;
print(x == y);
print(y > x);
if (y > x) {
print("y is greater than x");
}
}
此示例使用比较运算符生成布尔结果,这些结果控制 if 语句,在条件为真时打印消息。
$ dart main.dart false true y is greater than x
仅当两个运算对象都为 true 时,逻辑 AND (&&) 运算符才返回 true。
void main() {
var a = true && true;
var b = true && false;
var c = false && true;
var d = false && false;
print(a);
print(b);
print(c);
print(d);
}
这演示了 &&,只有第一种情况返回 true。
$ dart main.dart true false false false
只要至少一个运算对象为 true,逻辑 OR (||) 运算符就返回 true。
void main() {
var a = true || true;
var b = true || false;
var c = false || true;
var d = false || false;
print(a);
print(b);
print(c);
print(d);
}
四种情况中有三种返回 true,因为只有两个运算对象都为 false 时结果才为 false。
$ dart main.dart true true true false
否定运算符 ! 用于反转布尔值。
void main() {
print(!true);
print(!false);
print(!(4 < 3));
}
这显示了 ! 将 true 转换为 false,并将一个表达式求值为 true。
$ dart main.dart false true true
Dart 比较运算符
比较运算符(也称为关系运算符)用于比较值并返回布尔结果,这对于代码中的决策至关重要。
| 符号 | 含义 |
|---|---|
< | 小于 |
<= | 小于或等于 |
> | 大于 |
>= | 大于或等于 |
== | 等于 |
!= | 不等于 |
上表列出了 Dart 中的比较运算符。
void main() {
print(3 < 4);
print(3 == 4);
print(4 >= 3);
print(4 != 3);
}
此示例使用 == 运算符比较整数的相等性(与某些使用 = 的语言不同),返回布尔结果。
$ dart main.dart true false true true
Dart 按位运算符
按位运算符用于操作数字的二进制表示,执行逐位操作,这对于标志管理等底层任务很有用。
| 符号 | 含义 |
|---|---|
& | 按位与 |
| | 按位或 |
^ | 按位异或 |
~ | 按位非 |
<< | 左移 |
>> | 右移 |
当两个对应位都为 1 时,按位 AND (&) 运算符才产生 1。
00110 & 00011 = 00010
对于 6 (00110) 和 3 (00011),结果是 2 (00010)。
void main() {
print(6 & 3);
}
$ dart main.dart 2
如果任一位为 1,则按位 OR (|) 运算符产生 1。
00110 | 00011 = 00111
对于 6 和 3,结果是 7 (00111)。
void main() {
print(6 | 3);
}
$ dart main.dart 7
如果只有一位为 1,则按位 XOR (^) 运算符产生 1。
00110 ^ 00011 = 00101
对于 6 和 3,结果是 5 (00101)。
void main() {
print(6 ^ 3);
}
$ dart main.dart 5
Dart 三元运算符
三元运算符 ?: 提供了一种简洁的条件表达式,它根据布尔条件评估两个表达式中的一个。
condition ? expr1 : expr2
如果条件为 true,则评估 expr1;否则,评估 expr2。
void main() {
var age = 18;
var isAdult = (age >= 18) ? true : false;
if (isAdult) {
print("he is adult");
} else {
print("he is minor");
}
}
此示例使用三元运算符根据年龄设置 isAdult,然后使用 if 语句打印一条消息。
$ dart main.dart he is adult
Dart 展开运算符
展开运算符 ... 将集合的所有元素插入到另一个集合中,从而简化列表、集合或映射的构建。
void main() {
var vals = [1, 2, 3];
var vals2 = [...vals, 4, 5, 6];
print(vals);
print(vals2);
}
这会将 vals 展开到 vals2 中,添加更多元素以创建新列表。
$ dart main.dart [1, 2, 3] [1, 2, 3, 4, 5, 6]
Dart 级联运算符
级联运算符 .. 允许对同一对象执行多个操作,从而提高代码的流畅性和可读性。
class User {
var fname;
var lname;
var occupation;
String toString() {
return "$fname $lname is a $occupation";
}
}
void main() {
var u = User()
..fname = "John"
..lname = "Doe"
..occupation = "gardener";
print(u);
}
此示例使用级联初始化 User 对象的属性,然后打印其字符串表示形式。
$ dart main.dart John Doe is a gardener
Dart `is` 和 `is!` 运算符
is 和 is! 运算符在运行时检查对象的类型,如果类型匹配或不匹配,则分别返回 true。
class Base {}
class Derived extends Base {}
void main() {
var b = Base();
var d = Derived();
print(d is Base);
print(d is! Base);
print(b is Derived);
print(d is Object);
print(d is! Object);
}
这会检查类型关系,显示继承和对象类型属性。
$ dart main.dart true false false true false
Dart 空感知运算符
Dart 的空感知运算符(如 ?? 和 ??=)可以安全地处理 null 值,提供默认值或条件赋值以防止与 null 相关的错误。
void main() {
String? name;
// Null-coalescing operator
String displayName = name ?? "Guest";
print(displayName);
// Null-aware assignment
name ??= "Anonymous";
print(name);
name ??= "User";
print(name);
}
如果 name 为 null,则 ?? 运算符提供默认值;如果变量为 null,则 ??= 运算符为其赋值,否则保持不变。
$ dart main.dart Guest Anonymous Anonymous
Dart 条件成员访问运算符
条件成员访问运算符 ?. 可以安全地访问对象的属性或方法,如果对象为 null,则返回 null,从而避免运行时错误。
void main() {
String? text;
// Conditional member access
int? length = text?.length;
print(length);
text = "Hello";
length = text?.length;
print(length);
}
这会安全地访问 length 属性,当 text 为 null 时返回 null,当不为 null 时返回实际长度。
$ dart main.dart null 5
Dart 类型转换运算符
类型转换运算符 as 在运行时将对象转换为特定类型,如果转换无效则抛出异常,这对于使用动态类型或接口类型非常有用。
void main() {
var value = "Dart";
// Type cast
String text = value as String;
print(text.toUpperCase());
// Safe cast with is check
if (value is String) {
String safeText = value as String;
print(safeText.length);
}
}
这会将 value 转换为 String,允许进行特定于 String 的操作,并演示了带有类型检查的安全转换。
$ dart main.dart DART 4
Dart 运算符优先级
运算符优先级决定了求值运算符的顺序,它解决了表达式中的歧义,以确保结果一致。
void main() {
print(3 + 5 * 6);
print((3 + 5) * 6);
print(!true || true);
print(!(true || true));
}
乘法比加法具有更高的优先级,因此首先计算 5 * 6,得到 33。括号会覆盖此优先级,得到 48。否定优先于 ||,这会影响逻辑结果。
$ dart main.dart 33 48 true false
Dart 运算符优先级表
下表列出了 Dart 中的运算符优先级,从最高到最低。优先级较高的运算符在优先级较低的运算符之前进行求值。同一行的运算符具有相等的优先级,并根据结合性规则进行求值。
| 优先级 | 运算符 | 描述 |
|---|---|---|
| 1 (最高) | [], (), ., ?. | 成员访问、函数调用 |
| 2 | ++, --, ~ | 后缀递增/递减、按位非 |
| 3 | ++, --, +, -, ! | 前缀递增/递减、一元加/减、逻辑非 |
| 4 | *, /, %, ~/ | 乘法 |
| 5 | +, - | 加法 |
| 6 | >>, << | 按位移位 |
| 7 | >, <, >=, <=, is, is! | 关系、类型测试 |
| 8 | ==, != | 相等 |
| 9 | & | 按位与 |
| 10 | ^ | 按位异或 |
| 11 | | | 按位或 |
| 12 | && | 逻辑与 |
| 13 | || | 逻辑或 |
| 14 | ?? | 空合并 |
| 15 | ? : | 条件(三元) |
| 16 | =, +=, -=, *=, /=, %=, ~/=, &=, |=, ^=, <<=, >>=, ??= | 赋值 |
| 17 (最低) | , | 逗号 |
请参考此表来理解 Dart 如何求值复杂表达式,并避免由于运算符优先级而产生意外结果。
结合性规则
结合性决定了相等优先级的运算符的求值顺序。大多数运算符(如 / 和 *)是左到右的,而赋值和一元运算符是右到左的。
void main() {
print(9 / 3 * 3);
var j = 0;
j *= 3 + 1;
print(j);
}
表达式 9 / 3 * 3 按从左到右的顺序计算为 (9 / 3) * 3,得到 9。复合赋值 *= 是从右到左的,因此先计算 3 + 1,然后将其乘以 j。
$ dart main.dart 9.0 0
来源
本教程涵盖了 Dart 运算符、它们在表达式中的作用以及优先级和结合性如何影响求值。
作者
列出 所有 Dart 教程。