Dart 运算符和操作符详细总结
基于Dart官方API文档与实践经验整理
目录
概述
Dart提供了丰富的运算符集合,用于执行各种操作。运算符本质上是具有特殊语法的方法,大多数运算符都可以被重载。
核心特性
- 丰富的运算符集合:涵盖算术、比较、逻辑、位操作等
- 运算符重载:可以为自定义类定义运算符行为
- 空安全运算符:支持空安全的运算符(??、??=、?.等)
- 级联运算符:允许在同一对象上执行多个操作
- 类型运算符:用于类型检查和转换
- 优先级明确:清晰的运算符优先级和结合性规则
运算符分类
dart
// 算术运算符
int sum = 5 + 3; // 加法
int diff = 10 - 4; // 减法
int product = 6 * 7; // 乘法
double quotient = 15 / 4; // 除法
// 比较运算符
bool isEqual = (5 == 5); // 相等
bool isGreater = (10 > 5); // 大于
// 逻辑运算符
bool result = true && false; // 逻辑与
bool result2 = true || false; // 逻辑或
// 赋值运算符
int x = 10; // 赋值
x += 5; // 复合赋值
// 条件运算符
String name = user?.name ?? 'Unknown'; // 空合并
// 级联运算符
list..add(1)..add(2)..sort(); // 级联调用
算术运算符
1. 基本算术运算符
dart
void demonstrateArithmeticOperators() {
int a = 10, b = 3;
double x = 10.5, y = 3.2;
// 加法 (+)
print('$a + $b = ${a + b}'); // 10 + 3 = 13
print('$x + $y = ${x + y}'); // 10.5 + 3.2 = 13.7
// 减法 (-)
print('$a - $b = ${a - b}'); // 10 - 3 = 7
print('$x - $y = ${x - y}'); // 10.5 - 3.2 = 7.3
// 乘法 (*)
print('$a * $b = ${a * b}'); // 10 * 3 = 30
print('$x * $y = ${x * y}'); // 10.5 * 3.2 = 33.6
// 除法 (/)
print('$a / $b = ${a / b}'); // 10 / 3 = 3.3333333333333335
print('$x / $y = ${x / y}'); // 10.5 / 3.2 = 3.28125
// 整除 (~/)
print('$a ~/ $b = ${a ~/ b}'); // 10 ~/ 3 = 3
print('${x.toInt()} ~/ ${y.toInt()} = ${x.toInt() ~/ y.toInt()}'); // 10 ~/ 3 = 3
// 取模 (%)
print('$a % $b = ${a % b}'); // 10 % 3 = 1
print('$x % $y = ${x % y}'); // 10.5 % 3.2 = 0.8999999999999995
}
2. 一元算术运算符
dart
void demonstrateUnaryOperators() {
int number = 5;
double decimal = 3.14;
// 一元加号 (+)
print('+$number = ${+number}'); // +5 = 5
print('+$decimal = ${+decimal}'); // +3.14 = 3.14
// 一元减号 (-)
print('-$number = ${-number}'); // -5 = -5
print('-$decimal = ${-decimal}'); // -3.14 = -3.14
// 前置递增 (++var)
int a = 10;
print('++a: ${++a}'); // ++a: 11 (a现在是11)
// 后置递增 (var++)
int b = 10;
print('b++: ${b++}'); // b++: 10 (b现在是11)
print('b现在是: $b'); // b现在是: 11
// 前置递减 (--var)
int c = 10;
print('--c: ${--c}'); // --c: 9 (c现在是9)
// 后置递减 (var--)
int d = 10;
print('d--: ${d--}'); // d--: 10 (d现在是9)
print('d现在是: $d'); // d现在是: 9
}
3. 算术运算符的特殊情况
dart
void demonstrateSpecialCases() {
// 整数溢出
int maxInt = 9223372036854775807; // 64位系统的最大int值
print('maxInt + 1 = ${maxInt + 1}'); // 溢出,结果为负数
// 浮点数特殊值
double positive = 1.0;
double negative = -1.0;
double zero = 0.0;
print('1.0 / 0.0 = ${positive / zero}'); // Infinity
print('-1.0 / 0.0 = ${negative / zero}'); // -Infinity
print('0.0 / 0.0 = ${zero / zero}'); // NaN
// 检查特殊值
double inf = double.infinity;
double nan = double.nan;
print('isInfinite: ${inf.isInfinite}'); // true
print('isNaN: ${nan.isNaN}'); // true
print('isFinite: ${(3.14).isFinite}'); // true
// 精度问题
double result = 0.1 + 0.2;
print('0.1 + 0.2 = $result'); // 0.30000000000000004
print('0.1 + 0.2 == 0.3: ${result == 0.3}'); // false
// 正确的浮点数比较
bool isEqual = (result - 0.3).abs() < 1e-10;
print('近似相等: $isEqual'); // true
}
4. 字符串和列表的算术运算
dart
void demonstrateStringListArithmetic() {
// 字符串连接
String firstName = 'John';
String lastName = 'Doe';
String fullName = firstName + ' ' + lastName;
print('全名: $fullName'); // 全名: John Doe
// 字符串重复
String star = '*';
String stars = star * 5;
print('星号: $stars'); // 星号: *****
// 列表连接
List<int> list1 = [1, 2, 3];
List<int> list2 = [4, 5, 6];
List<int> combined = list1 + list2;
print('合并列表: $combined'); // 合并列表: [1, 2, 3, 4, 5, 6]
// 注意:不能对列表使用乘法运算符
// List<int> repeated = list1 * 3; // 编译错误
// 但可以通过其他方式实现重复
List<int> repeated = [];
for (int i = 0; i < 3; i++) {
repeated.addAll(list1);
}
print('重复列表: $repeated'); // 重复列表: [1, 2, 3, 1, 2, 3, 1, 2, 3]
}
比较运算符
1. 相等性运算符
dart
void demonstrateEqualityOperators() {
// 基本类型比较
int a = 5;
int b = 5;
int c = 10;
print('$a == $b: ${a == b}'); // 5 == 5: true
print('$a != $c: ${a != c}'); // 5 != 10: true
// 字符串比较
String str1 = 'hello';
String str2 = 'hello';
String str3 = 'Hello';
print("'$str1' == '$str2': ${str1 == str2}"); // 'hello' == 'hello': true
print("'$str1' == '$str3': ${str1 == str3}"); // 'hello' == 'Hello': false
// 对象比较
List<int> list1 = [1, 2, 3];
List<int> list2 = [1, 2, 3];
List<int> list3 = list1;
print('list1 == list2: ${list1 == list2}'); // true (内容相同)
print('identical(list1, list2): ${identical(list1, list2)}'); // false (不同对象)
print('identical(list1, list3): ${identical(list1, list3)}'); // true (同一对象)
// 空值比较
String? nullString = null;
String? anotherNull = null;
String? notNull = 'value';
print('null == null: ${nullString == anotherNull}'); // true
print('null == "value": ${nullString == notNull}'); // false
}
2. 关系运算符
dart
void demonstrateRelationalOperators() {
int x = 10;
int y = 20;
double a = 15.5;
double b = 15.5;
// 小于 (<)
print('$x < $y: ${x < y}'); // 10 < 20: true
print('$y < $x: ${y < x}'); // 20 < 10: false
// 小于等于 (<=)
print('$x <= $y: ${x <= y}'); // 10 <= 20: true
print('$a <= $b: ${a <= b}'); // 15.5 <= 15.5: true
// 大于 (>)
print('$y > $x: ${y > x}'); // 20 > 10: true
print('$x > $y: ${x > y}'); // 10 > 20: false
// 大于等于 (>=)
print('$y >= $x: ${y >= x}'); // 20 >= 10: true
print('$a >= $b: ${a >= b}'); // 15.5 >= 15.5: true
// 字符串比较(按字典序)
String str1 = 'apple';
String str2 = 'banana';
String str3 = 'Apple';
print("'$str1' < '$str2': ${str1.compareTo(str2) < 0}"); // true
print("'$str1' > '$str3': ${str1.compareTo(str3) > 0}"); // true (小写字母ASCII值大)
// 使用Comparable接口
DateTime date1 = DateTime(2023, 1, 1);
DateTime date2 = DateTime(2023, 12, 31);
print('$date1 < $date2: ${date1.isBefore(date2)}'); // true
print('$date2 > $date1: ${date2.isAfter(date1)}'); // true
}
3. 自定义类的比较
dart
class Person implements Comparable<Person> {
final String name;
final int age;
Person(this.name, this.age);
@override
int compareTo(Person other) {
// 首先按年龄比较,然后按姓名比较
int ageComparison = age.compareTo(other.age);
if (ageComparison != 0) {
return ageComparison;
}
return name.compareTo(other.name);
}
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Person &&
runtimeType == other.runtimeType &&
name == other.name &&
age == other.age;
@override
int get hashCode => Object.hash(name, age);
// 重载比较运算符
bool operator <(Person other) => compareTo(other) < 0;
bool operator <=(Person other) => compareTo(other) <= 0;
bool operator >(Person other) => compareTo(other) > 0;
bool operator >=(Person other) => compareTo(other) >= 0;
@override
String toString() => 'Person(name: $name, age: $age)';
}
void demonstrateCustomComparison() {
Person alice = Person('Alice', 25);
Person bob = Person('Bob', 30);
Person charlie = Person('Charlie', 25);
print('$alice == $bob: ${alice == bob}'); // false
print('$alice < $bob: ${alice < bob}'); // true (年龄小)
print('$alice < $charlie: ${alice < charlie}'); // true (年龄相同,姓名字典序)
// 排序
List<Person> people = [bob, charlie, alice];
people.sort();
print('排序后: $people');
// 排序后: [Person(name: Alice, age: 25), Person(name: Charlie, age: 25), Person(name: Bob, age: 30)]
}
逻辑运算符
1. 基本逻辑运算符
dart
void demonstrateLogicalOperators() {
bool a = true;
bool b = false;
bool c = true;
// 逻辑与 (&&)
print('$a && $b = ${a && b}'); // true && false = false
print('$a && $c = ${a && c}'); // true && true = true
// 逻辑或 (||)
print('$a || $b = ${a || b}'); // true || false = true
print('$b || false = ${b || false}'); // false || false = false
// 逻辑非 (!)
print('!$a = ${!a}'); // !true = false
print('!$b = ${!b}'); // !false = true
// 复合逻辑表达式
bool result1 = a && b || c; // (true && false) || true = true
bool result2 = a && (b || c); // true && (false || true) = true
bool result3 = !(a && b); // !(true && false) = true
print('a && b || c = $result1');
print('a && (b || c) = $result2');
print('!(a && b) = $result3');
}
2. 短路求值
dart
bool expensiveOperation() {
print('执行昂贵的操作...');
return true;
}
bool anotherExpensiveOperation() {
print('执行另一个昂贵的操作...');
return false;
}
void demonstrateShortCircuitEvaluation() {
print('=== 逻辑与的短路求值 ===');
bool result1 = false && expensiveOperation();
print('结果: $result1'); // expensiveOperation()不会被调用
bool result2 = true && expensiveOperation();
print('结果: $result2'); // expensiveOperation()会被调用
print('\n=== 逻辑或的短路求值 ===');
bool result3 = true || anotherExpensiveOperation();
print('结果: $result3'); // anotherExpensiveOperation()不会被调用
bool result4 = false || anotherExpensiveOperation();
print('结果: $result4'); // anotherExpensiveOperation()会被调用
}
3. 实际应用场景
dart
class User {
String? name;
int? age;
bool isActive;
List<String> roles;
User({this.name, this.age, this.isActive = false, this.roles = const []});
bool get isValid => name != null && name!.isNotEmpty && age != null && age! > 0;
bool get isAdmin => isActive && roles.contains('admin');
bool get canEdit => isActive && (roles.contains('admin') || roles.contains('editor'));
}
void demonstrateLogicalInPractice() {
User user1 = User(name: 'Alice', age: 25, isActive: true, roles: ['user']);
User user2 = User(name: 'Bob', age: 30, isActive: true, roles: ['admin']);
User user3 = User(name: '', age: -1, isActive: false);
// 验证用户
print('user1有效: ${user1.isValid}'); // true
print('user3有效: ${user3.isValid}'); // false
// 权限检查
print('user1是管理员: ${user1.isAdmin}'); // false
print('user2是管理员: ${user2.isAdmin}'); // true
print('user1可编辑: ${user1.canEdit}'); // false
print('user2可编辑: ${user2.canEdit}'); // true
// 复杂条件
bool canAccessAdminPanel = user2.isActive &&
user2.age != null &&
user2.age! >= 18 &&
(user2.roles.contains('admin') || user2.roles.contains('moderator'));
print('user2可访问管理面板: $canAccessAdminPanel'); // true
}
4. 逻辑运算符与空安全
dart
void demonstrateLogicalWithNullSafety() {
String? nullableString = null;
String? anotherString = 'hello';
// 安全的逻辑运算
bool result1 = nullableString != null && nullableString.isNotEmpty;
print('nullableString不为空且不为空字符串: $result1'); // false
bool result2 = anotherString != null && anotherString.isNotEmpty;
print('anotherString不为空且不为空字符串: $result2'); // true
// 使用空合并运算符
bool result3 = (nullableString ?? '').isNotEmpty;
print('使用空合并的结果: $result3'); // false
// 组合使用
bool isValidInput(String? input) {
return input != null &&
input.trim().isNotEmpty &&
input.length >= 3;
}
print('isValidInput(null): ${isValidInput(null)}'); // false
print('isValidInput(""): ${isValidInput("")}'); // false
print('isValidInput("hi"): ${isValidInput("hi")}'); // false
print('isValidInput("hello"): ${isValidInput("hello")}'); // true
}
位运算符
1. 基本位运算符
dart
void demonstrateBitwiseOperators() {
int a = 12; // 二进制: 1100
int b = 10; // 二进制: 1010
print('a = $a (${a.toRadixString(2).padLeft(8, '0')})');
print('b = $b (${b.toRadixString(2).padLeft(8, '0')})');
print('');
// 按位与 (&)
int andResult = a & b; // 1100 & 1010 = 1000 (8)
print('$a & $b = $andResult (${andResult.toRadixString(2).padLeft(8, '0')})');
// 按位或 (|)
int orResult = a | b; // 1100 | 1010 = 1110 (14)
print('$a | $b = $orResult (${orResult.toRadixString(2).padLeft(8, '0')})');
// 按位异或 (^)
int xorResult = a ^ b; // 1100 ^ 1010 = 0110 (6)
print('$a ^ $b = $xorResult (${xorResult.toRadixString(2).padLeft(8, '0')})');
// 按位取反 (~)
int notA = ~a; // ~1100 = ...11110011 (取决于系统位数)
print('~$a = $notA (${(notA & 0xFF).toRadixString(2).padLeft(8, '0')})');
// 左移 (<<)
int leftShift = a << 2; // 1100 << 2 = 110000 (48)
print('$a << 2 = $leftShift (${leftShift.toRadixString(2).padLeft(8, '0')})');
// 右移 (>>)
int rightShift = a >> 2; // 1100 >> 2 = 11 (3)
print('$a >> 2 = $rightShift (${rightShift.toRadixString(2).padLeft(8, '0')})');
}
2. 位运算的实际应用
dart
// 权限系统使用位运算
class Permissions {
static const int read = 1; // 0001
static const int write = 2; // 0010
static const int execute = 4; // 0100
static const int delete = 8; // 1000
int _permissions = 0;
// 添加权限
void grant(int permission) {
_permissions |= permission;
}
// 撤销权限
void revoke(int permission) {
_permissions &= ~permission;
}
// 检查权限
bool hasPermission(int permission) {
return (_permissions & permission) == permission;
}
// 切换权限
void toggle(int permission) {
_permissions ^= permission;
}
// 获取所有权限
int get permissions => _permissions;
// 清除所有权限
void clear() {
_permissions = 0;
}
@override
String toString() {
List<String> perms = [];
if (hasPermission(read)) perms.add('READ');
if (hasPermission(write)) perms.add('WRITE');
if (hasPermission(execute)) perms.add('EXECUTE');
if (hasPermission(delete)) perms.add('DELETE');
return perms.isEmpty ? 'NO_PERMISSIONS' : perms.join(', ');
}
}
void demonstratePermissionSystem() {
Permissions userPerms = Permissions();
print('初始权限: $userPerms');
// 授予读写权限
userPerms.grant(Permissions.read | Permissions.write);
print('授予读写权限后: $userPerms');
// 检查权限
print('有读权限: ${userPerms.hasPermission(Permissions.read)}');
print('有删除权限: ${userPerms.hasPermission(Permissions.delete)}');
// 添加执行权限
userPerms.grant(Permissions.execute);
print('添加执行权限后: $userPerms');
// 撤销写权限
userPerms.revoke(Permissions.write);
print('撤销写权限后: $userPerms');
// 切换删除权限
userPerms.toggle(Permissions.delete);
print('切换删除权限后: $userPerms');
userPerms.toggle(Permissions.delete);
print('再次切换删除权限后: $userPerms');
}
3. 位掩码和标志位
dart
// 状态标志位示例
enum TaskStatus {
pending, // 0001
running, // 0010
completed, // 0100
failed, // 1000
}
class TaskManager {
int _statusFlags = 0;
void setStatus(TaskStatus status) {
_statusFlags |= (1 << status.index);
}
void clearStatus(TaskStatus status) {
_statusFlags &= ~(1 << status.index);
}
bool hasStatus(TaskStatus status) {
return (_statusFlags & (1 << status.index)) != 0;
}
List<TaskStatus> get activeStatuses {
List<TaskStatus> statuses = [];
for (TaskStatus status in TaskStatus.values) {
if (hasStatus(status)) {
statuses.add(status);
}
}
return statuses;
}
void reset() {
_statusFlags = 0;
}
}
void demonstrateBitFlags() {
TaskManager manager = TaskManager();
// 设置多个状态
manager.setStatus(TaskStatus.pending);
manager.setStatus(TaskStatus.running);
print('当前状态: ${manager.activeStatuses}');
// 检查状态
print('是否待处理: ${manager.hasStatus(TaskStatus.pending)}');
print('是否已完成: ${manager.hasStatus(TaskStatus.completed)}');
// 更新状态
manager.clearStatus(TaskStatus.pending);
manager.setStatus(TaskStatus.completed);
print('更新后状态: ${manager.activeStatuses}');
}
4. 位运算优化技巧
dart
class BitTricks {
// 检查数字是否为2的幂
static bool isPowerOfTwo(int n) {
return n > 0 && (n & (n - 1)) == 0;
}
// 计算数字中1的个数(汉明权重)
static int countBits(int n) {
int count = 0;
while (n != 0) {
count++;
n &= (n - 1); // 清除最低位的1
}
return count;
}
// 交换两个数(不使用临时变量)
static void swapNumbers(List<int> arr, int i, int j) {
if (i != j) {
arr[i] ^= arr[j];
arr[j] ^= arr[i];
arr[i] ^= arr[j];
}
}
// 获取最低位的1
static int getLowestBit(int n) {
return n & (-n);
}
// 清除最低位的1
static int clearLowestBit(int n) {
return n & (n - 1);
}
// 设置第n位为1
static int setBit(int number, int position) {
return number | (1 << position);
}
// 清除第n位
static int clearBit(int number, int position) {
return number & ~(1 << position);
}
// 切换第n位
static int toggleBit(int number, int position) {
return number ^ (1 << position);
}
// 检查第n位是否为1
static bool isBitSet(int number, int position) {
return (number & (1 << position)) != 0;
}
}
void demonstrateBitTricks() {
// 测试2的幂
List<int> numbers = [1, 2, 3, 4, 8, 15, 16, 32];
for (int num in numbers) {
print('$num 是2的幂: ${BitTricks.isPowerOfTwo(num)}');
}
// 计算位数
int value = 42; // 101010
print('$value 的二进制中有 ${BitTricks.countBits(value)} 个1');
// 位操作
int original = 10; // 1010
print('原始值: $original (${original.toRadixString(2)})');
int withBitSet = BitTricks.setBit(original, 0); // 设置第0位
print('设置第0位后: $withBitSet (${withBitSet.toRadixString(2)})');
int withBitCleared = BitTricks.clearBit(withBitSet, 1); // 清除第1位
print('清除第1位后: $withBitCleared (${withBitCleared.toRadixString(2)})');
int toggled = BitTricks.toggleBit(withBitCleared, 2); // 切换第2位
print('切换第2位后: $toggled (${toggled.toRadixString(2)})');
}
赋值运算符
1. 基本赋值运算符
dart
void demonstrateBasicAssignment() {
// 简单赋值 (=)
int a = 10;
double b = 3.14;
String c = 'Hello';
bool d = true;
print('a = $a, b = $b, c = $c, d = $d');
// 多重赋值(通过元组或记录)
(int x, int y) = (5, 10);
print('x = $x, y = $y');
// 列表赋值
List<int> numbers = [1, 2, 3];
List<String> names = ['Alice', 'Bob'];
print('numbers = $numbers');
print('names = $names');
// 对象赋值
Map<String, int> scores = {'Alice': 95, 'Bob': 87};
print('scores = $scores');
}
2. 复合赋值运算符
dart
void demonstrateCompoundAssignment() {
int a = 10;
double b = 5.5;
String str = 'Hello';
List<int> list = [1, 2, 3];
print('初始值: a=$a, b=$b, str="$str", list=$list');
// 算术复合赋值
a += 5; // a = a + 5
print('a += 5: $a');
a -= 3; // a = a - 3
print('a -= 3: $a');
a *= 2; // a = a * 2
print('a *= 2: $a');
b /= 2; // b = b / 2
print('b /= 2: $b');
a ~/= 3; // a = a ~/ 3 (整除)
print('a ~/= 3: $a');
int remainder = 17;
remainder %= 5; // remainder = remainder % 5
print('17 %= 5: $remainder');
// 字符串复合赋值
str += ' World';
print('str += " World": "$str"');
// 位运算复合赋值
int flags = 12; // 1100
flags &= 10; // 1100 & 1010 = 1000
print('flags &= 10: $flags (${flags.toRadixString(2)})');
flags |= 3; // 1000 | 0011 = 1011
print('flags |= 3: $flags (${flags.toRadixString(2)})');
flags ^= 7; // 1011 ^ 0111 = 1100
print('flags ^= 7: $flags (${flags.toRadixString(2)})');
flags <<= 1; // 1100 << 1 = 11000
print('flags <<= 1: $flags (${flags.toRadixString(2)})');
flags >>= 2; // 11000 >> 2 = 110
print('flags >>= 2: $flags (${flags.toRadixString(2)})');
}
3. 空赋值运算符
dart
void demonstrateNullAssignment() {
String? name;
String? email;
int? age;
// 空合并赋值运算符 (??=)
// 只有当变量为null时才赋值
name ??= 'Default Name';
print('name ??= "Default Name": $name'); // Default Name
name ??= 'Another Name';
print('name ??= "Another Name": $name'); // Default Name (不变)
email ??= 'default@example.com';
print('email ??= "default@example.com": $email');
age ??= 18;
print('age ??= 18: $age');
// 实际应用场景
Map<String, String> config = {};
config['host'] ??= 'localhost';
config['port'] ??= '8080';
config['protocol'] ??= 'http';
print('配置: $config');
// 再次赋值不会改变已有值
config['host'] ??= 'production.com';
config['port'] ??= '443';
print('再次赋值后: $config'); // 值不变
}
4. 赋值运算符的返回值
dart
void demonstrateAssignmentReturn() {
int a, b, c;
// 赋值运算符返回被赋的值
a = b = c = 10;
print('a=$a, b=$b, c=$c');
// 复合赋值也返回值
int x = 5;
int y = (x += 3); // x变为8,y也是8
print('x=$x, y=$y');
// 在条件表达式中使用赋值
int value = 0;
while ((value += 2) < 10) {
print('当前值: $value');
}
print('最终值: $value');
// 在函数调用中使用赋值
void processValue(int val) {
print('处理值: $val');
}
int number = 0;
processValue(number = 42); // 赋值并传递
print('number现在是: $number');
}
5. 列表和映射的赋值操作
dart
void demonstrateCollectionAssignment() {
// 列表赋值
List<int> numbers = [1, 2, 3, 4, 5];
print('原始列表: $numbers');
// 索引赋值
numbers[0] = 10;
numbers[2] = 30;
print('修改后: $numbers');
// 映射赋值
Map<String, int> scores = {'Alice': 85, 'Bob': 90};
print('原始分数: $scores');
// 键值赋值
scores['Alice'] = 95;
scores['Charlie'] = 88;
print('修改后: $scores');
// 使用复合赋值
scores['Alice'] += 5;
scores['Bob'] -= 2;
print('复合赋值后: $scores');
// 空合并赋值在集合中的使用
scores['David'] ??= 75;
scores['Alice'] ??= 60; // 不会改变,因为Alice已存在
print('空合并赋值后: $scores');
// 列表的复合赋值(需要自定义)
List<int> list1 = [1, 2, 3];
List<int> list2 = [4, 5, 6];
list1.addAll(list2); // 相当于 list1 += list2 的效果
print('合并后的列表: $list1');
}
6. 赋值运算符与对象
dart
class Counter {
int value;
Counter(this.value);
// 重载复合赋值运算符的效果需要通过方法实现
Counter operator +(int increment) {
return Counter(value + increment);
}
Counter operator -(int decrement) {
return Counter(value - decrement);
}
void increment([int step = 1]) {
value += step;
}
void decrement([int step = 1]) {
value -= step;
}
@override
String toString() => 'Counter($value)';
}
void demonstrateObjectAssignment() {
Counter counter = Counter(10);
print('初始计数器: $counter');
// 对象的赋值创建新对象
Counter newCounter = counter + 5;
print('原计数器: $counter');
print('新计数器: $newCounter');
// 修改对象内部状态
counter.increment(3);
print('增加后的计数器: $counter');
// 引用赋值
Counter aliasCounter = counter;
aliasCounter.increment(2);
print('原计数器: $counter'); // 也会改变
print('别名计数器: $aliasCounter'); // 指向同一对象
// 深拷贝 vs 浅拷贝
List<int> originalList = [1, 2, 3];
List<int> shallowCopy = originalList; // 浅拷贝(引用)
List<int> deepCopy = List.from(originalList); // 深拷贝
originalList.add(4);
print('原始列表: $originalList'); // [1, 2, 3, 4]
print('浅拷贝: $shallowCopy'); // [1, 2, 3, 4] (受影响)
print('深拷贝: $deepCopy'); // [1, 2, 3] (不受影响)
}
类型运算符
1. is 运算符(类型检查)
dart
void demonstrateIsOperator() {
var value = 'Hello World';
// 基本类型检查
print('value is String: ${value is String}'); // true
print('value is int: ${value is int}'); // false
print('value is Object: ${value is Object}'); // true
// 数字类型检查
num number = 42;
print('number is num: ${number is num}'); // true
print('number is int: ${number is int}'); // true
print('number is double: ${number is double}'); // false
double decimal = 3.14;
print('decimal is num: ${decimal is num}'); // true
print('decimal is double: ${decimal is double}'); // true
print('decimal is int: ${decimal is int}'); // false
// 集合类型检查
List<String> names = ['Alice', 'Bob'];
print('names is List: ${names is List}'); // true
print('names is List<String>: ${names is List<String>}'); // true
print('names is List<int>: ${names is List<int>}'); // false
print('names is Iterable: ${names is Iterable}'); // true
Map<String, int> scores = {'Alice': 95};
print('scores is Map: ${scores is Map}'); // true
print('scores is Map<String, int>: ${scores is Map<String, int>}'); // true
}
2. is! 运算符(类型否定检查)
dart
void demonstrateIsNotOperator() {
var value = 123;
// 类型否定检查
print('value is! String: ${value is! String}'); // true
print('value is! int: ${value is! int}'); // false
print('value is! num: ${value is! num}'); // false
// 在条件语句中使用
if (value is! String) {
print('value不是字符串,它是${value.runtimeType}');
}
// 与null检查结合
String? nullableString;
print('nullableString is! String: ${nullableString is! String}'); // true
nullableString = 'Hello';
print('nullableString is! String: ${nullableString is! String}'); // false
}
3. as 运算符(类型转换)
dart
void demonstrateAsOperator() {
// 安全的向下转型
Object obj = 'Hello World';
// 将Object转换为String
String str = obj as String;
print('转换后的字符串: $str');
print('字符串长度: ${str.length}');
// 数字转换
num numValue = 42;
int intValue = numValue as int;
print('转换后的整数: $intValue');
// 集合转换
List<Object> objectList = ['a', 'b', 'c'];
List<String> stringList = objectList as List<String>;
print('转换后的字符串列表: $stringList');
// 危险的转换(运行时错误)
try {
Object wrongType = 123;
String wrongCast = wrongType as String; // 抛出TypeError
print('这行不会执行: $wrongCast');
} catch (e) {
print('类型转换错误: $e');
}
}
4. 安全的类型转换模式
dart
// 安全转换函数
T? safeCast<T>(dynamic value) {
return value is T ? value as T : null;
}
// 带默认值的安全转换
T safeCastWithDefault<T>(dynamic value, T defaultValue) {
return value is T ? value as T : defaultValue;
}
void demonstrateSafeTypeCasting() {
// 使用安全转换
Object mixedValue = 'Hello';
String? safeString = safeCast<String>(mixedValue);
int? safeInt = safeCast<int>(mixedValue);
print('安全字符串转换: $safeString'); // Hello
print('安全整数转换: $safeInt'); // null
// 使用带默认值的安全转换
String stringResult = safeCastWithDefault<String>(mixedValue, 'Default');
int intResult = safeCastWithDefault<int>(mixedValue, 0);
print('字符串结果: $stringResult'); // Hello
print('整数结果: $intResult'); // 0
// 实际应用:处理JSON数据
Map<String, dynamic> json = {
'name': 'Alice',
'age': 25,
'score': 95.5,
'active': true,
};
String name = safeCastWithDefault<String>(json['name'], 'Unknown');
int age = safeCastWithDefault<int>(json['age'], 0);
double score = safeCastWithDefault<double>(json['score'], 0.0);
bool isActive = safeCastWithDefault<bool>(json['active'], false);
print('姓名: $name, 年龄: $age, 分数: $score, 活跃: $isActive');
}
5. 类型检查在继承中的应用
dart
abstract class Animal {
String name;
Animal(this.name);
void makeSound();
}
class Dog extends Animal {
String breed;
Dog(String name, this.breed) : super(name);
@override
void makeSound() => print('$name汪汪叫');
void wagTail() => print('$name摇尾巴');
}
class Cat extends Animal {
bool isIndoor;
Cat(String name, this.isIndoor) : super(name);
@override
void makeSound() => print('$name喵喵叫');
void climb() => print('$name爬树');
}
class Bird extends Animal {
double wingspan;
Bird(String name, this.wingspan) : super(name);
@override
void makeSound() => print('$name啁啾叫');
void fly() => print('$name飞翔');
}
void demonstrateInheritanceTypeChecking() {
List<Animal> animals = [
Dog('旺财', '金毛'),
Cat('咪咪', true),
Bird('小黄', 20.5),
Dog('大黄', '土狗'),
];
print('=== 类型检查和特定行为 ===');
for (Animal animal in animals) {
print('\n${animal.name} (${animal.runtimeType}):');
animal.makeSound();
// 类型检查和安全转换
if (animal is Dog) {
Dog dog = animal; // 自动类型提升
print('品种: ${dog.breed}');
dog.wagTail();
} else if (animal is Cat) {
Cat cat = animal as Cat; // 显式转换
print('室内猫: ${cat.isIndoor}');
cat.climb();
} else if (animal is Bird) {
(animal as Bird).fly(); // 内联转换
print('翼展: ${(animal as Bird).wingspan}cm');
}
}
print('\n=== 统计不同类型的动物 ===');
int dogCount = animals.where((animal) => animal is Dog).length;
int catCount = animals.where((animal) => animal is Cat).length;
int birdCount = animals.where((animal) => animal is Bird).length;
print('狗: $dogCount只, 猫: $catCount只, 鸟: $birdCount只');
print('\n=== 类型过滤 ===');
List<Dog> dogs = animals.whereType<Dog>().toList();
List<Cat> cats = animals.whereType<Cat>().toList();
print('所有狗: ${dogs.map((d) => '${d.name}(${d.breed})').join(', ')}');
print('所有猫: ${cats.map((c) => '${c.name}(室内:${c.isIndoor})').join(', ')}');
}
6. 泛型中的类型检查
dart
class Container<T> {
T _value;
Container(this._value);
T get value => _value;
set value(T newValue) {
_value = newValue;
}
// 检查是否可以存储特定类型
bool canStore<R>() {
return _value is R;
}
// 安全获取特定类型的值
R? getAs<R>() {
return _value is R ? _value as R : null;
}
// 类型转换
Container<R> cast<R>() {
if (_value is R) {
return Container<R>(_value as R);
}
throw TypeError();
}
@override
String toString() => 'Container<$T>($_value)';
}
void demonstrateGenericTypeChecking() {
// 创建不同类型的容器
Container<Object> objectContainer = Container<Object>('Hello');
Container<String> stringContainer = Container<String>('World');
Container<int> intContainer = Container<int>(42);
print('对象容器: $objectContainer');
print('字符串容器: $stringContainer');
print('整数容器: $intContainer');
// 类型检查
print('\n=== 类型检查 ===');
print('objectContainer可以存储String: ${objectContainer.canStore<String>()}');
print('objectContainer可以存储int: ${objectContainer.canStore<int>()}');
print('stringContainer可以存储String: ${stringContainer.canStore<String>()}');
print('intContainer可以存储String: ${intContainer.canStore<String>()}');
// 安全获取
print('\n=== 安全获取 ===');
String? strFromObject = objectContainer.getAs<String>();
int? intFromObject = objectContainer.getAs<int>();
String? strFromString = stringContainer.getAs<String>();
print('从对象容器获取字符串: $strFromObject');
print('从对象容器获取整数: $intFromObject');
print('从字符串容器获取字符串: $strFromString');
// 类型转换
print('\n=== 类型转换 ===');
try {
Container<String> convertedContainer = objectContainer.cast<String>();
print('转换成功: $convertedContainer');
} catch (e) {
print('转换失败: $e');
}
}
条件运算符
1. 三元条件运算符 (? :)
dart
void demonstrateTernaryOperator() {
int age = 18;
String status = age >= 18 ? '成年人' : '未成年人';
print('年龄$age,状态:$status');
// 嵌套三元运算符
int score = 85;
String grade = score >= 90 ? 'A' :
score >= 80 ? 'B' :
score >= 70 ? 'C' :
score >= 60 ? 'D' : 'F';
print('分数$score,等级:$grade');
// 在函数调用中使用
void printMessage(bool isSuccess) {
print(isSuccess ? '操作成功' : '操作失败');
}
printMessage(true);
printMessage(false);
// 返回不同类型(需要有公共基类)
bool useString = true;
Object result = useString ? 'Hello' : 42;
print('结果: $result (${result.runtimeType})');
// 在集合初始化中使用
bool includOptional = false;
List<String> items = [
'item1',
'item2',
if (includOptional) 'optional_item', // 更好的方式
// includOptional ? 'optional_item' : null, // 这样会包含null
].where((item) => item != null).cast<String>().toList();
print('项目列表: $items');
}
2. 空合并运算符 (??)
dart
void demonstrateNullCoalescingOperator() {
String? name;
String? email;
// 基本用法:如果左侧为null,使用右侧的值
String displayName = name ?? 'Guest';
String contactEmail = email ?? 'no-email@example.com';
print('显示名称: $displayName');
print('联系邮箱: $contactEmail');
// 链式空合并
String? firstName;
String? lastName;
String? nickname;
String finalName = firstName ?? lastName ?? nickname ?? 'Anonymous';
print('最终名称: $finalName');
// 与方法调用结合
String? getUserName() => null;
String? getDefaultName() => 'DefaultUser';
String userName = getUserName() ?? getDefaultName() ?? 'Unknown';
print('用户名: $userName');
// 在集合中使用
List<String>? optionalList;
List<String> safeList = optionalList ?? [];
print('安全列表: $safeList');
Map<String, String>? optionalMap;
Map<String, String> safeMap = optionalMap ?? {};
print('安全映射: $safeMap');
// 数值的空合并
int? optionalAge;
double? optionalHeight;
int age = optionalAge ?? 0;
double height = optionalHeight ?? 0.0;
print('年龄: $age, 身高: $height');
}
3. 空合并赋值运算符 (??=)
dart
class UserPreferences {
String? theme;
String? language;
int? fontSize;
bool? notifications;
void setDefaults() {
// 只有当值为null时才设置默认值
theme ??= 'light';
language ??= 'zh-CN';
fontSize ??= 14;
notifications ??= true;
}
@override
String toString() {
return 'UserPreferences(theme: $theme, language: $language, fontSize: $fontSize, notifications: $notifications)';
}
}
void demonstrateNullCoalescingAssignment() {
UserPreferences prefs = UserPreferences();
print('初始偏好: $prefs');
prefs.setDefaults();
print('设置默认值后: $prefs');
// 再次设置默认值不会改变已有值
prefs.theme = 'dark';
prefs.setDefaults();
print('再次设置默认值后: $prefs');
// 在映射中使用
Map<String, int> cache = {};
String key1 = 'user_123';
String key2 = 'user_456';
// 如果键不存在,设置默认值
cache[key1] ??= 0;
cache[key1] = cache[key1]! + 1; // 增加计数
cache[key2] ??= 0;
cache[key2] = cache[key2]! + 1;
cache[key1] ??= 0;
cache[key1] = cache[key1]! + 1;
print('缓存计数: $cache');
// 在列表中使用
Map<String, List<String>> groups = {};
void addToGroup(String groupName, String item) {
groups[groupName] ??= [];
groups[groupName]!.add(item);
}
addToGroup('fruits', 'apple');
addToGroup('fruits', 'banana');
addToGroup('vegetables', 'carrot');
addToGroup('fruits', 'orange');
print('分组: $groups');
}
4. 条件成员访问运算符 (?.)
dart
class Address {
String street;
String city;
String? zipCode;
Address(this.street, this.city, [this.zipCode]);
@override
String toString() => '$street, $city ${zipCode ?? ''}';
}
class Person {
String name;
Address? address;
List<String>? hobbies;
Person(this.name, [this.address, this.hobbies]);
String? getZipCode() => address?.zipCode;
@override
String toString() => 'Person(name: $name, address: $address)';
}
void demonstrateConditionalAccess() {
// 创建有地址的人
Person person1 = Person(
'Alice',
Address('123 Main St', 'New York', '10001'),
['reading', 'swimming']
);
// 创建没有地址的人
Person person2 = Person('Bob');
print('=== 条件成员访问 ===');
// 安全访问嵌套属性
print('${person1.name}的邮编: ${person1.address?.zipCode}');
print('${person2.name}的邮编: ${person2.address?.zipCode}');
// 安全方法调用
print('${person1.name}的城市长度: ${person1.address?.city.length}');
print('${person2.name}的城市长度: ${person2.address?.city.length}');
// 链式安全访问
print('${person1.name}的街道首字母: ${person1.address?.street[0]}');
print('${person2.name}的街道首字母: ${person2.address?.street[0]}');
// 安全访问集合
print('${person1.name}的爱好数量: ${person1.hobbies?.length}');
print('${person2.name}的爱好数量: ${person2.hobbies?.length}');
print('${person1.name}的第一个爱好: ${person1.hobbies?[0]}');
print('${person2.name}的第一个爱好: ${person2.hobbies?[0]}');
// 结合空合并运算符
String person1City = person1.address?.city ?? 'Unknown';
String person2City = person2.address?.city ?? 'Unknown';
print('${person1.name}的城市: $person1City');
print('${person2.name}的城市: $person2City');
}
5. 条件运算符的组合使用
dart
class ApiResponse<T> {
final bool success;
final T? data;
final String? error;
final int? statusCode;
ApiResponse({
required this.success,
this.data,
this.error,
this.statusCode,
});
@override
String toString() => 'ApiResponse(success: $success, data: $data, error: $error, statusCode: $statusCode)';
}
class User {
final int id;
final String name;
final String email;
final bool isActive;
User({required this.id, required this.name, required this.email, this.isActive = true});
@override
String toString() => 'User(id: $id, name: $name, email: $email, active: $isActive)';
}
void demonstrateComplexConditionalOperators() {
// 模拟API响应
ApiResponse<User>? successResponse = ApiResponse(
success: true,
data: User(id: 1, name: 'Alice', email: 'alice@example.com'),
statusCode: 200,
);
ApiResponse<User>? errorResponse = ApiResponse(
success: false,
error: 'User not found',
statusCode: 404,
);
ApiResponse<User>? nullResponse;
print('=== 复杂条件运算符组合 ===');
// 安全获取用户信息
String getUserInfo(ApiResponse<User>? response) {
return response?.success == true
? 'User: ${response?.data?.name ?? 'Unknown'} (${response?.data?.email ?? 'No email'})'
: 'Error: ${response?.error ?? 'Unknown error'}';
}
print('成功响应: ${getUserInfo(successResponse)}');
print('错误响应: ${getUserInfo(errorResponse)}');
print('空响应: ${getUserInfo(nullResponse)}');
// 复杂的条件逻辑
String getStatusMessage(ApiResponse<User>? response) {
// 多层条件检查
return response == null
? 'No response'
: !response.success
? 'Request failed: ${response.error ?? 'Unknown error'}'
: response.data == null
? 'No user data'
: response.data!.isActive
? 'Active user: ${response.data!.name}'
: 'Inactive user: ${response.data!.name}';
}
print('\n=== 状态消息 ===');
print('成功响应状态: ${getStatusMessage(successResponse)}');
print('错误响应状态: ${getStatusMessage(errorResponse)}');
print('空响应状态: ${getStatusMessage(nullResponse)}');
// 使用条件运算符进行数据转换
Map<String, dynamic> responseToJson(ApiResponse<User>? response) {
return {
'status': response?.success ?? false ? 'success' : 'error',
'message': response?.success ?? false
? 'Request completed successfully'
: response?.error ?? 'Unknown error occurred',
'user': response?.data != null
? {
'id': response!.data!.id,
'name': response.data!.name,
'email': response.data!.email,
'active': response.data!.isActive,
}
: null,
'statusCode': response?.statusCode ?? 500,
};
}
print('\n=== JSON转换 ===');
print('成功响应JSON: ${responseToJson(successResponse)}');
print('错误响应JSON: ${responseToJson(errorResponse)}');
print('空响应JSON: ${responseToJson(nullResponse)}');
}
6. 条件运算符的性能考虑
dart
class ExpensiveOperation {
static int callCount = 0;
static String performOperation(String input) {
callCount++;
print('执行昂贵操作 #$callCount: $input');
// 模拟耗时操作
return input.toUpperCase();
}
static String? performNullableOperation(String input) {
callCount++;
print('执行可空操作 #$callCount: $input');
return input.isEmpty ? null : input.toLowerCase();
}
}
void demonstrateConditionalPerformance() {
print('=== 条件运算符性能考虑 ===');
// 短路求值的好处
String? input1 = null;
String? input2 = 'Hello';
ExpensiveOperation.callCount = 0;
// 使用 ?? 运算符(短路求值)
String result1 = input1 ?? ExpensiveOperation.performOperation('default1');
String result2 = input2 ?? ExpensiveOperation.performOperation('default2');
print('结果1: $result1');
print('结果2: $result2');
print('总调用次数: ${ExpensiveOperation.callCount}'); // 只调用1次
print('\n--- 对比:总是计算两边 ---');
ExpensiveOperation.callCount = 0;
// 如果不使用短路求值(错误示例)
String getValue(String? input, String defaultValue) {
String def = ExpensiveOperation.performOperation(defaultValue);
return input ?? def; // 总是计算默认值
}
String result3 = getValue(null, 'default3');
String result4 = getValue('World', 'default4');
print('结果3: $result3');
print('结果4: $result4');
print('总调用次数: ${ExpensiveOperation.callCount}'); // 调用2次
// 缓存计算结果
print('\n--- 使用缓存优化 ---');
Map<String, String> cache = {};
String getCachedValue(String? input, String key) {
return input ?? (cache[key] ??= ExpensiveOperation.performOperation(key));
}
ExpensiveOperation.callCount = 0;
String cached1 = getCachedValue(null, 'cached_key');
String cached2 = getCachedValue(null, 'cached_key'); // 使用缓存
String cached3 = getCachedValue('Direct', 'cached_key'); // 不使用缓存
print('缓存结果1: $cached1');
print('缓存结果2: $cached2');
print('缓存结果3: $cached3');
print('总调用次数: ${ExpensiveOperation.callCount}'); // 只调用1次
print('缓存内容: $cache');
}
级联运算符
1. 基本级联运算符 (..)
dart
class Person {
String? name;
int? age;
String? email;
List<String> hobbies = [];
void setName(String name) => this.name = name;
void setAge(int age) => this.age = age;
void setEmail(String email) => this.email = email;
void addHobby(String hobby) => hobbies.add(hobby);
@override
String toString() => 'Person(name: $name, age: $age, email: $email, hobbies: $hobbies)';
}
void demonstrateBasicCascade() {
// 不使用级联运算符的传统方式
Person person1 = Person();
person1.setName('Alice');
person1.setAge(25);
person1.setEmail('alice@example.com');
person1.addHobby('reading');
person1.addHobby('swimming');
print('传统方式: $person1');
// 使用级联运算符
Person person2 = Person()
..setName('Bob')
..setAge(30)
..setEmail('bob@example.com')
..addHobby('gaming')
..addHobby('cooking');
print('级联方式: $person2');
// 级联运算符与属性访问
Person person3 = Person()
..name = 'Charlie'
..age = 28
..email = 'charlie@example.com'
..hobbies.add('music')
..hobbies.add('travel');
print('属性级联: $person3');
}
2. 空安全级联运算符 (?..)
dart
void demonstrateNullAwareCascade() {
List<int>? nullableList = [1, 2, 3];
List<int>? emptyList = null;
// 使用空安全级联运算符
nullableList
?..add(4)
..add(5)
..sort();
print('nullableList: $nullableList');
// 对null对象使用空安全级联
emptyList
?..add(1) // 这些操作都不会执行
..add(2)
..sort();
print('emptyList: $emptyList'); // 仍然是null
// 级联运算符与集合
List<String> names = []
..add('Alice')
..add('Bob')
..add('Charlie')
..sort()
..shuffle();
print('names: $names');
}
其他运算符
1. 函数调用运算符 ()
dart
class Calculator {
double Function(double, double) operation;
Calculator(this.operation);
// 实现call方法,使对象可调用
double call(double a, double b) => operation(a, b);
}
void demonstrateCallOperator() {
// 创建可调用对象
Calculator adder = Calculator((a, b) => a + b);
Calculator multiplier = Calculator((a, b) => a * b);
// 使用函数调用运算符
print('5 + 3 = ${adder(5, 3)}'); // 使用call方法
print('4 * 6 = ${multiplier(4, 6)}'); // 使用call方法
// 函数作为第一类对象
List<int Function(int)> functions = [
(x) => x * 2,
(x) => x + 1,
(x) => x * x,
];
int value = 5;
for (var func in functions) {
value = func(value);
print('当前值: $value');
}
}
2. 索引运算符 []
dart
class Matrix {
List<List<int>> _data;
Matrix(this._data);
// 实现索引运算符
List<int> operator [](int row) => _data[row];
// 实现索引赋值运算符
void operator []=(int row, List<int> value) {
_data[row] = value;
}
// 自定义二维索引
int getValue(int row, int col) => _data[row][col];
void setValue(int row, int col, int value) {
_data[row][col] = value;
}
@override
String toString() => _data.toString();
}
void demonstrateIndexOperator() {
Matrix matrix = Matrix([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]);
print('原始矩阵: $matrix');
// 使用索引运算符访问
print('第一行: ${matrix[0]}');
print('第二行第三列: ${matrix[1][2]}');
// 使用索引运算符修改
matrix[0] = [10, 20, 30];
matrix[1][1] = 50;
print('修改后矩阵: $matrix');
// Map的索引运算符
Map<String, int> scores = {'Alice': 95, 'Bob': 87};
print('Alice的分数: ${scores['Alice']}');
scores['Charlie'] = 92;
print('添加Charlie后: $scores');
}
3. 成员访问运算符 (.)
dart
class Address {
String street;
String city;
Address(this.street, this.city);
@override
String toString() => '$street, $city';
}
class Person {
String name;
Address address;
Person(this.name, this.address);
String getFullAddress() => '${address.street}, ${address.city}';
}
void demonstrateMemberAccess() {
Person person = Person('Alice', Address('123 Main St', 'New York'));
// 成员访问运算符
print('姓名: ${person.name}');
print('街道: ${person.address.street}');
print('城市: ${person.address.city}');
print('完整地址: ${person.getFullAddress()}');
// 链式成员访问
String cityName = person.address.city.toUpperCase();
print('大写城市名: $cityName');
}
运算符重载
1. 算术运算符重载
dart
class Vector2D {
final double x, y;
const Vector2D(this.x, this.y);
// 加法运算符重载
Vector2D operator +(Vector2D other) {
return Vector2D(x + other.x, y + other.y);
}
// 减法运算符重载
Vector2D operator -(Vector2D other) {
return Vector2D(x - other.x, y - other.y);
}
// 乘法运算符重载(标量乘法)
Vector2D operator *(double scalar) {
return Vector2D(x * scalar, y * scalar);
}
// 除法运算符重载
Vector2D operator /(double scalar) {
if (scalar == 0) throw ArgumentError('除数不能为0');
return Vector2D(x / scalar, y / scalar);
}
// 一元负号运算符重载
Vector2D operator -() {
return Vector2D(-x, -y);
}
// 相等运算符重载
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Vector2D && x == other.x && y == other.y;
@override
int get hashCode => Object.hash(x, y);
// 索引运算符重载
double operator [](int index) {
switch (index) {
case 0: return x;
case 1: return y;
default: throw RangeError('索引必须是0或1');
}
}
// 计算向量的模长
double get magnitude => math.sqrt(x * x + y * y);
@override
String toString() => 'Vector2D($x, $y)';
}
void demonstrateOperatorOverloading() {
Vector2D v1 = Vector2D(3, 4);
Vector2D v2 = Vector2D(1, 2);
print('v1: $v1');
print('v2: $v2');
print('v1的模长: ${v1.magnitude}');
// 使用重载的运算符
Vector2D sum = v1 + v2;
Vector2D diff = v1 - v2;
Vector2D scaled = v1 * 2;
Vector2D divided = v1 / 2;
Vector2D negated = -v1;
print('v1 + v2 = $sum');
print('v1 - v2 = $diff');
print('v1 * 2 = $scaled');
print('v1 / 2 = $divided');
print('-v1 = $negated');
// 使用索引运算符
print('v1[0] = ${v1[0]}, v1[1] = ${v1[1]}');
// 相等性比较
Vector2D v3 = Vector2D(3, 4);
print('v1 == v3: ${v1 == v3}');
print('v1 == v2: ${v1 == v2}');
}
2. 比较运算符重载
dart
class Student implements Comparable<Student> {
final String name;
final int score;
final int age;
Student(this.name, this.score, this.age);
@override
int compareTo(Student other) {
// 首先按分数降序排列
int scoreComparison = other.score.compareTo(score);
if (scoreComparison != 0) return scoreComparison;
// 分数相同则按年龄升序排列
int ageComparison = age.compareTo(other.age);
if (ageComparison != 0) return ageComparison;
// 年龄也相同则按姓名字母序排列
return name.compareTo(other.name);
}
// 重载比较运算符
bool operator <(Student other) => compareTo(other) < 0;
bool operator <=(Student other) => compareTo(other) <= 0;
bool operator >(Student other) => compareTo(other) > 0;
bool operator >=(Student other) => compareTo(other) >= 0;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Student &&
name == other.name &&
score == other.score &&
age == other.age;
@override
int get hashCode => Object.hash(name, score, age);
@override
String toString() => 'Student(name: $name, score: $score, age: $age)';
}
void demonstrateComparisonOverloading() {
List<Student> students = [
Student('Alice', 95, 20),
Student('Bob', 87, 22),
Student('Charlie', 95, 19),
Student('David', 87, 21),
Student('Eve', 95, 19),
];
print('原始学生列表:');
students.forEach(print);
// 使用重载的比较运算符排序
students.sort();
print('\n排序后的学生列表:');
students.forEach(print);
// 使用重载的比较运算符
Student alice = students.first;
Student bob = students[3];
print('\n比较运算符测试:');
print('$alice > $bob: ${alice > bob}');
print('$alice <= $bob: ${alice <= bob}');
}
运算符优先级和结合性
优先级表格(从高到低)
dart
void demonstrateOperatorPrecedence() {
// 优先级演示
int result1 = 2 + 3 * 4; // 14, 不是 20
int result2 = (2 + 3) * 4; // 20
print('2 + 3 * 4 = $result1');
print('(2 + 3) * 4 = $result2');
// 逻辑运算符优先级
bool result3 = true || false && false; // true, 不是 false
bool result4 = (true || false) && false; // false
print('true || false && false = $result3');
print('(true || false) && false = $result4');
// 位运算符优先级
int result5 = 5 | 3 & 1; // 5 (先计算 3 & 1 = 1, 然后 5 | 1 = 5)
int result6 = (5 | 3) & 1; // 0 (先计算 5 | 3 = 7, 然后 7 & 1 = 1)
print('5 | 3 & 1 = $result5');
print('(5 | 3) & 1 = $result6');
// 赋值运算符优先级最低
int a = 1;
int b = 2;
int c = a = b + 1; // 等价于 c = (a = (b + 1))
print('a = $a, b = $b, c = $c');
}
完整优先级表
优先级 | 运算符 | 描述 | 结合性 |
---|---|---|---|
16 | () [] . ?. |
后缀 | 左到右 |
15 | -expr !expr ~expr ++expr --expr await expr |
一元前缀 | 无 |
14 | expr++ expr-- |
一元后缀 | 无 |
13 | * / % ~/ |
乘法 | 左到右 |
12 | + - |
加法 | 左到右 |
11 | << >> >>> |
位移 | 左到右 |
10 | & |
按位与 | 左到右 |
9 | ^ |
按位异或 | 左到右 |
8 | ` | ` | 按位或 |
7 | >= > <= < as is is! |
关系和类型测试 | 左到右 |
6 | == != |
相等 | 左到右 |
5 | && |
逻辑与 | 左到右 |
4 | ` | ` | |
3 | ?? |
空合并 | 左到右 |
2 | ? : |
条件 | 右到左 |
1 | .. ?.. |
级联 | 左到右 |
0 | = *= /= += -= &= ` |
= ^=` `~/=` `%=` `<<=` `>>=` `>>>=` `??=` |
赋值 |
实际应用示例
1. 数据验证和处理
dart
class DataProcessor {
// 使用运算符重载创建流畅的API
static bool Function(dynamic) operator +(bool Function(dynamic) f1, bool Function(dynamic) f2) {
return (value) => f1(value) && f2(value);
}
static bool isNotNull(dynamic value) => value != null;
static bool isNotEmpty(dynamic value) => value is String ? value.isNotEmpty : true;
static bool isEmail(dynamic value) => value is String ?
RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(value) : false;
static bool isMinLength(int min) => (dynamic value) =>
value is String ? value.length >= min : true;
static void processData(Map<String, dynamic> data) {
// 使用条件运算符和逻辑运算符进行验证
String name = data['name'] ?? '';
String email = data['email'] ?? '';
int age = data['age'] ?? 0;
// 复合验证
bool isValidName = name.isNotEmpty && name.length >= 2;
bool isValidEmail = email.isNotEmpty && isEmail(email);
bool isValidAge = age > 0 && age < 150;
print('数据验证结果:');
print(' 姓名有效: $isValidName (值: "$name")');
print(' 邮箱有效: $isValidEmail (值: "$email")');
print(' 年龄有效: $isValidAge (值: $age)');
// 使用级联运算符处理有效数据
if (isValidName && isValidEmail && isValidAge) {
Map<String, dynamic> processedData = {}
..['name'] = name.trim().toLowerCase()
..['email'] = email.trim().toLowerCase()
..['age'] = age
..['processed_at'] = DateTime.now().toIso8601String()
..['status'] = 'valid';
print('处理后的数据: $processedData');
}
}
}
2. 构建器模式的高级应用
dart
class QueryBuilder {
String _table = '';
List<String> _columns = [];
List<String> _conditions = [];
List<String> _orderBy = [];
int? _limit;
QueryBuilder from(String table) {
_table = table;
return this;
}
QueryBuilder select(List<String> columns) {
_columns = columns;
return this;
}
QueryBuilder where(String condition) {
_conditions.add(condition);
return this;
}
QueryBuilder orderBy(String column, [String direction = 'ASC']) {
_orderBy.add('$column $direction');
return this;
}
QueryBuilder limit(int count) {
_limit = count;
return this;
}
String build() {
StringBuffer query = StringBuffer();
// SELECT子句
query.write('SELECT ');
query.write(_columns.isEmpty ? '*' : _columns.join(', '));
// FROM子句
query.write(' FROM $_table');
// WHERE子句
if (_conditions.isNotEmpty) {
query.write(' WHERE ${_conditions.join(' AND ')}');
}
// ORDER BY子句
if (_orderBy.isNotEmpty) {
query.write(' ORDER BY ${_orderBy.join(', ')}');
}
// LIMIT子句
if (_limit != null) {
query.write(' LIMIT $_limit');
}
return query.toString();
}
}
void demonstrateQueryBuilder() {
// 使用级联运算符构建复杂查询
String query1 = QueryBuilder()
..from('users')
..select(['name', 'email', 'age'])
..where('age >= 18')
..where('status = "active"')
..orderBy('name')
..limit(10);
print('查询1: ${query1.build()}');
String query2 = QueryBuilder()
..from('products')
..where('price > 100')
..where('category = "electronics"')
..orderBy('price', 'DESC')
..limit(5);
print('查询2: ${query2.build()}');
}
性能考虑
1. 运算符重载的性能影响
dart
class PerformanceTest {
static void compareOperatorPerformance() {
const int iterations = 1000000;
// 测试基本运算符
Stopwatch sw1 = Stopwatch()..start();
for (int i = 0; i < iterations; i++) {
int result = i + i * 2 - i ~/ 2;
}
sw1.stop();
print('基本运算符时间: ${sw1.elapsedMilliseconds}ms');
// 测试重载运算符
Vector2D v1 = Vector2D(1, 2);
Vector2D v2 = Vector2D(3, 4);
Stopwatch sw2 = Stopwatch()..start();
for (int i = 0; i < iterations; i++) {
Vector2D result = v1 + v2 - v1 * 0.5;
}
sw2.stop();
print('重载运算符时间: ${sw2.elapsedMilliseconds}ms');
// 测试方法调用
Stopwatch sw3 = Stopwatch()..start();
for (int i = 0; i < iterations; i++) {
Vector2D temp = v1.add(v2);
Vector2D result = temp.subtract(v1.multiply(0.5));
}
sw3.stop();
print('方法调用时间: ${sw3.elapsedMilliseconds}ms');
}
}
extension Vector2DMethods on Vector2D {
Vector2D add(Vector2D other) => Vector2D(x + other.x, y + other.y);
Vector2D subtract(Vector2D other) => Vector2D(x - other.x, y - other.y);
Vector2D multiply(double scalar) => Vector2D(x * scalar, y * scalar);
}
常见陷阱和错误
1. 运算符优先级陷阱
dart
void demonstrateCommonPitfalls() {
// 陷阱1: 逻辑运算符优先级
bool a = true;
bool b = false;
bool c = true;
// 错误理解:(a || b) && c
// 实际执行:a || (b && c)
bool result1 = a || b && c;
print('a || b && c = $result1'); // true
// 正确的写法
bool result2 = (a || b) && c;
print('(a || b) && c = $result2'); // true
// 陷阱2: 位运算符优先级
int x = 5; // 101
int y = 3; // 011
// 错误理解:(x & y) == 1
// 实际执行:x & (y == 1)
bool result3 = x & y == 1; // 编译错误!
// 正确的写法
bool result4 = (x & y) == 1;
print('(x & y) == 1 = $result4'); // true
// 陷阱3: 空合并运算符的优先级
String? name = null;
String? backup = 'default';
// 可能的误解
String result5 = name ?? backup.toUpperCase(); // 正确:name ?? (backup.toUpperCase())
print('name ?? backup.toUpperCase() = $result5'); // DEFAULT
// 陷阱4: 级联运算符的返回值
List<int> list = [3, 1, 4]..sort(); // 返回List<int>
print('排序后的列表: $list'); // [1, 3, 4]
// 错误用法
// int length = [1, 2, 3]..add(4).length; // 错误!级联返回原对象
// 正确用法
List<int> tempList = [1, 2, 3]..add(4);
int length = tempList.length;
print('列表长度: $length'); // 4
}
最佳实践
1. 运算符重载最佳实践
dart
class Money {
final int cents; // 使用分为单位避免浮点数精度问题
final String currency;
const Money(this.cents, this.currency);
// 工厂构造函数
factory Money.fromDollars(double dollars, String currency) {
return Money((dollars * 100).round(), currency);
}
// 只重载有意义的运算符
Money operator +(Money other) {
if (currency != other.currency) {
throw ArgumentError('不能加不同货币: $currency + ${other.currency}');
}
return Money(cents + other.cents, currency);
}
Money operator -(Money other) {
if (currency != other.currency) {
throw ArgumentError('不能减不同货币: $currency - ${other.currency}');
}
return Money(cents - other.cents, currency);
}
Money operator *(double multiplier) {
return Money((cents * multiplier).round(), currency);
}
Money operator /(double divisor) {
if (divisor == 0) throw ArgumentError('除数不能为0');
return Money((cents / divisor).round(), currency);
}
// 比较运算符
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Money && cents == other.cents && currency == other.currency;
@override
int get hashCode => Object.hash(cents, currency);
bool operator <(Money other) {
if (currency != other.currency) {
throw ArgumentError('不能比较不同货币');
}
return cents < other.cents;
}
bool operator >(Money other) {
if (currency != other.currency) {
throw ArgumentError('不能比较不同货币');
}
return cents > other.cents;
}
double get dollars => cents / 100.0;
@override
String toString() => '${dollars.toStringAsFixed(2)} $currency';
}
void demonstrateBestPractices() {
Money price1 = Money.fromDollars(19.99, 'USD');
Money price2 = Money.fromDollars(5.50, 'USD');
// 运算符重载使代码更直观
Money total = price1 + price2;
Money discounted = total * 0.9;
print('价格1: $price1');
print('价格2: $price2');
print('总计: $total');
print('打折后: $discounted');
// 比较运算符
if (price1 > price2) {
print('$price1 比 $price2 贵');
}
}
2. 条件运算符最佳实践
dart
class UserService {
// 使用空合并运算符提供默认值
static String getDisplayName(String? firstName, String? lastName, String? username) {
return '${firstName ?? ''} ${lastName ?? ''}'.trim().ifEmpty(() => username ?? 'Guest');
}
// 使用条件运算符简化逻辑
static String getUserStatus(bool isActive, DateTime? lastLogin) {
return !isActive
? 'Inactive'
: lastLogin == null
? 'Never logged in'
: DateTime.now().difference(lastLogin).inDays > 30
? 'Inactive (30+ days)'
: 'Active';
}
// 使用级联运算符初始化对象
static Map<String, dynamic> createUserProfile({
required String name,
required String email,
String? avatar,
List<String>? interests,
}) {
return <String, dynamic>{}
..['name'] = name
..['email'] = email
..['avatar'] = avatar ?? 'default-avatar.png'
..['interests'] = interests ?? []
..['created_at'] = DateTime.now().toIso8601String()
..['status'] = 'active';
}
}
extension StringExtensions on String {
String ifEmpty(String Function() defaultValue) {
return isEmpty ? defaultValue() : this;
}
}
总结
Dart的运算符系统提供了强大而灵活的表达能力,通过掌握以下关键概念:
- 丰富的运算符类型:算术、比较、逻辑、位、赋值、类型、条件等
- 运算符重载:为自定义类型定义直观的运算符行为
- 空安全运算符:安全处理可空值的强大工具
- 级联运算符:简化对象配置和链式调用
- 优先级和结合性:正确理解运算符的执行顺序
- 性能考虑:合理使用运算符避免性能问题
结合最佳实践和常见陷阱的避免,可以编写出更加简洁、可读和高效的Dart代码。记住要根据具体场景选择合适的运算符,并始终考虑代码的可读性和维护性。
本文档基于Dart 3.x版本整理,涵盖了运算符系统的核心概念和实际应用场景。