Dart 表达式
最后修改日期:2025 年 6 月 4 日
表达式是 Dart 程序的核心,它们能够执行产生值的计算。本教程将探讨 Dart 表达式,详细介绍运算符类型、求值规则以及级联符号等独特功能。
Dart 表达式概述
在 Dart 中,表达式是求值为一个值的代码结构,例如字面量、变量、运算符或函数调用。Dart 提供了多种多样的运算符和表达式类型,为各种编程任务提供简洁且富有表现力的代码。
| 表达式类型 | 描述 | Etitle="Dart 代码示例 |
|---|---|---|
| 字面量 | 直接的值表示 | 5, 'hello', true |
| 算术 | 数学运算 | a + b, x * y |
| 关系 | 比较运算 | a > b, x == y |
| 逻辑运算 | 布尔运算 | a && b, !flag |
| 条件表达式 | 三元运算符 | a ? b : c |
| 级联符号 | 连续操作 | obj..a()..b() |
| 赋值 | 赋值 | a = 5, b += 2 |
字面量表达式
字面量表达式直接在代码中表示固定值,支持 Dart 中的各种数据类型,包括整数(例如 42)、双精度浮点数(例如 3.14)、字符串(使用单引号、双引号或三引号)、布尔值(true、false)、列表、映射和 null 值。这些字面量提供了一种在程序中嵌入常量值的直接方式。
void main() {
// Numeric literals
int integer = 42;
double floating = 3.14159;
// String literals
String singles = 'Single quotes';
String doubles = "Double quotes";
String multiline = '''
Multi-line
string
''';
// Boolean literals
bool truthy = true;
bool falsy = false;
// List and Map literals
List<int> numbers = [1, 2, 3];
Map<String, int> ages = {'Alice': 25, 'Bob': 30};
print(integer);
print(floating);
print(singles);
print(doubles);
print(multiline);
print(truthy);
print(falsy);
print(numbers);
print(ages);
}
此示例展示了各种 Dart 字面量,演示了如何定义和打印整数、双精度浮点数、字符串(包括多行)、布尔值、列表和映射,突出了它们在代码中的直接用法。
$ dart run literals.dart
42
3.14159
Single quotes
Double quotes
Multi-line
string
[1, 2, 3]
{Alice: 25, Bob: 30}
算术表达式
Dart 支持通过加法 (+)、减法 (-)、乘法 (*)、除法 (/)、整数除法 (~/)、取模 (%) 和一元负号 (-) 等运算符进行标准的算术运算。除法运算符始终返回一个 double,而自增 (++) 和自减 (--) 运算符则修改值。这些运算符支持数学计算,包括混合类型运算。
void main() {
int a = 10;
int b = 3;
double c = 5.0;
// Basic operations
print('Addition: ${a + b}');
print('Subtraction: ${a - b}');
print('Multiplication: ${a * b}');
print('Division: ${a / b}');
print('Integer division: ${a ~/ b}');
print('Modulo: ${a % b}');
print('Unary minus: ${-a}');
// Mixed type arithmetic
print('Mixed addition: ${a + c}');
// Increment/decrement
int counter = 0;
print('Post-increment: ${counter++}');
print('After increment: $counter');
print('Pre-decrement: ${--counter}');
}
此示例演示了算术运算,包括基本计算、混合类型加法以及自增/自减运算,说明了 Dart 如何处理数学表达式。
$ dart run arithmetic.dart Addition: 13 Subtraction: 7 Multiplication: 30 Division: 3.3333333333333335 Integer division: 3 Modulo: 1 Unary minus: -10 Mixed addition: 15.0 Post-increment: 0 After increment: 1 Pre-decrement: 0
关系表达式和逻辑表达式
关系运算符,如等于 (==)、不等于 (!=)、大于 (>) 和小于 (<),会比较值以产生布尔结果。逻辑运算符,包括与 (&&)、或 (||) 和非 (!),用于组合布尔表达式。Dart 采用短路求值,跳过不必要的运算(例如,在 && 中,如果第一个操作数为 false),从而提高逻辑表达式的效率和安全性。
void main() {
int a = 5;
int b = 10;
// Relational operators
print('Equal: ${a == b}');
print('Not equal: ${a != b}');
print('Greater than: ${a > b}');
print('Less than: ${a < b}');
print('Greater or equal: ${a >= b}');
print('Less or equal: ${a <= b}');
// Logical operators
bool x = true;
bool y = false;
print('AND: ${x && y}');
print('OR: ${x || y}');
print('NOT: ${!x}');
// Short-circuit evaluation
String? name;
bool isValid = name != null && name.isNotEmpty;
print('Is valid: $isValid');
}
此示例说明了关系比较和逻辑运算,包括对可空字符串进行短路求值的演示,展示了 Dart 如何确保安全高效的表达式求值。
$ dart run relational_logical.dart Equal: false Not equal: true Greater than: false Less than: true Greater or equal: false Less or equal: true AND: false OR: true NOT: false Is valid: false
条件表达式
Dart 的条件表达式提供了简洁的决策制定结构。三元运算符 (?:) 充当紧凑的 if-else 语句,而空合并运算符 (??) 为 null 变量提供默认值。空感知运算符,如条件属性访问 (?.) 和空感知赋值 (??=),确保了可空类型的安全处理,使代码更加健壮和简洁。
void main() {
int age = 20;
// Ternary operator
String status = age >= 18 ? 'Adult' : 'Minor';
print('Status: $status');
// Null-coalescing operator
String? name;
String displayName = name ?? 'Guest';
print('Welcome, $displayName');
// Conditional property access
List<int>? numbers;
int? first = numbers?.first;
print('First number: $first');
// Null-aware assignment
name ??= 'Anonymous';
print('Name: $name');
}
此示例展示了条件表达式,包括用于基于年龄的状态的三元运算符、用于默认名称的空合并,以及用于安全列表访问和赋值的空感知运算符,展示了简洁的控制流。
$ dart run conditional.dart Status: Adult Welcome, Guest First number: null Name: Anonymous
级联符号
Dart 的级联符号 (..) 允许以流畅的方式对同一对象执行多个操作,并在每次操作后返回原始对象。此功能对于构建器样式的 API 尤其有用,它通过减少重复的对象引用来简化代码,提高了连续方法调用的可读性和可维护性。
class Person {
String name = '';
int age = 0;
void greet() => print('Hello, $name!');
void birthday() => age++;
}
void main() {
// Without cascade
Person p1 = Person();
p1.name = 'Alice';
p1.age = 30;
p1.greet();
// With cascade
Person p2 = Person()
..name = 'Bob'
..age = 25
..greet()
..birthday();
print('Bob\'s age: ${p2.age}');
// Nested cascades
StringBuffer sb = StringBuffer()
..write('Hello')
..write(' ')
..writeAll(['Dart', '!'], ' ');
print(sb.toString());
}
此示例使用 Person 类和 StringBuffer 对比了对象操作的传统符号和级联符号,展示了级联符号如何简化多个方法调用和属性赋值。
$ dart run cascade.dart Hello, Alice! Hello, Bob! Bob's age: 26 Hello Dart !
赋值表达式
Dart 中的赋值表达式使用基本赋值运算符 (=) 或复合运算符(如 +=、*= 和 ~/=)将值存储在变量中。这些表达式求值为赋给的值,从而实现链式赋值。空感知赋值 (??=) 仅在变量为 null 时才赋值,提供了一种设置默认值的安全方式。
void main() {
// Simple assignment
int x = 5;
print('x = $x');
// Compound assignment
x += 3;
print('x += 3 → $x');
x ~/= 2;
print('x ~/= 2 → $x');
// Assignment as expression
int y;
print('y = ${y = x * 2}');
// Null-aware assignment
int? z;
z ??= 10;
print('z = $z');
}
此示例演示了简单和复合运算、将表达式作为赋值以及空感知赋值,展示了 Dart 如何管理变量更新和默认值。
$ dart run assignment.dart x = 5 x += 3 → 8 x ~/= 2 → 4 y = 8 z = 10
表达式求值顺序
Dart 根据运算符的优先级和结合性来求值表达式。乘法等运算符的优先级高于加法,而括号会覆盖默认优先级。大多数运算符是左结合的,从左到右处理,但赋值运算符和条件运算符是右结合的,这保证了可预测的计算顺序。
void main() {
// Operator precedence
int result = 2 + 3 * 4;
print('2 + 3 * 4 = $result');
// Parentheses change order
result = (2 + 3) * 4;
print('(2 + 3) * 4 = $result');
// Left-associative operators
result = 10 - 4 - 2;
print('10 - 4 - 2 = $result');
// Right-associative operators
bool a = false, b = true, c = false;
bool logical = a && b || c;
print('a && b || c = $logical');
}
此示例说明了运算符优先级、括号的影响以及表达式求值中的结合性,展示了 Dart 如何系统地处理复杂表达式。
$ dart run evaluation_order.dart 2 + 3 * 4 = 14 (2 + 3) * 4 = 20 10 - 4 - 2 = 4 a && b || c = false
按位表达式
Dart 的按位运算符用于操作整数的位,从而实现设置标志或优化计算等底层操作。运算符包括与 (&)、或 (|)、异或 (^)、非 (~)、左移 (<<) 和右移 (>>)。这些运算符在需要直接位操作的场景(如图形处理或协议实现)中非常有用。
void main() {
int a = 5; // Binary: 0101
int b = 3; // Binary: 0011
// Bitwise operators
print('Bitwise AND: ${a & b}'); // 0101 & 0011 = 0001
print('Bitwise OR: ${a | b}'); // 0101 | 0011 = 0111
print('Bitwise XOR: ${a ^ b}'); // 0101 ^ 0011 = 0110
print('Bitwise NOT: ${~a}'); // ~0101 = ...1010 (inverts bits)
print('Left shift: ${a << 1}'); // 0101 << 1 = 1010
print('Right shift: ${a >> 1}'); // 0101 >> 1 = 0010
// Using bitwise for flags
int read = 1; // 0001
int write = 2; // 0010
int permissions = read | write; // 0011
print('Has read: ${(permissions & read) != 0}');
}
此示例演示了整数上的按位运算,包括与、或、异或、非和移位运算,以及一个用于管理权限标志的实际用例,突出了它们在底层编程中的实用性。
$ dart run bitwise.dart Bitwise AND: 1 Bitwise OR: 7 Bitwise XOR: 6 Bitwise NOT: -6 Left shift: 10 Right shift: 2 Has read: true
展开运算符表达式
Dart 中的展开运算符 (...) 可以展开集合的元素,从而能够简洁地合并或复制列表、集合或映射。空感知展开运算符 (...?) 可以安全地处理 null 集合,防止运行时错误。此功能简化了表达式中的集合操作,提高了代码的可读性和灵活性。
void main() {
// Spread operator with lists
List<int> part1 = [1, 2];
List<int> part2 = [3, 4];
List<int> combined = [...part1, ...part2, 5];
print('Combined list: $combined');
// Null-aware spread
List<int>? optional;
List<int> safeList = [...part1, ...?optional, 6];
print('Safe list: $safeList');
// Spread with maps
Map<String, int> map1 = {'a': 1, 'b': 2};
Map<String, int> map2 = {'c': 3};
Map<String, int> merged = {...map1, ...map2, 'd': 4};
print('Merged map: $merged');
// Nested spread
List<List<int>> nested = [
[1, 2],
[3, 4]
];
List<int> flattened = [...nested[0], ...nested[1]];
print('Flattened: $flattened');
}
此示例展示了用于合并列表和映射的展开运算符、用于安全处理可空集合的空感知展开,以及展平嵌套列表,展示了其在集合表达式中的强大功能。
$ dart run spread.dart
Combined list: [1, 2, 3, 4, 5]
Safe list: [1, 2, 6]
Merged map: {a: 1, b: 2, c: 3, d: 4}
Flattened: [1, 2, 3, 4]
Switch 表达式
Dart 的 switch 表达式提供了一种根据多个条件选择值的简洁方法。与传统的 switch 语句不同,switch 表达式可以直接用于赋值和返回值,使代码更具表现力并减少样板代码。Dart 在 switch 表达式中支持模式匹配和 null 安全,从而实现了强大且可读的分支逻辑。
void main() {
var grade = 'B';
var result = switch (grade) {
'A' => 'Excellent',
'B' => 'Good',
'C' => 'Average',
'D' => 'Below average',
'F' => 'Fail',
_ => 'Unknown',
};
print('Grade: $grade, Result: $result');
// Pattern matching with types
Object value = 42;
var type = switch (value) {
int i => 'Integer',
double d => 'Double',
String s => 'String',
_ => 'Other',
};
print('Type: $type');
}
此示例演示了 Dart 的 switch 表达式用于值选择和类型模式匹配。第一个 switch 将成绩映射到描述,第二个 switch 使用类型模式来确定值的类型。Switch 表达式提高了代码的清晰度,并减少了对冗长 if-else 链的需要。
来源
掌握 Dart 表达式对于编写高效且富有表现力的代码至关重要。从字面量到级联和展开运算符等高级功能,Dart 为各种编程需求提供了多功能工具。
作者
列出 所有 Dart 教程。