操作符(实例方法)

第1章已详细讨论过操作符,本文将从方法的角度再次讨论它。Dart多数的操作符,是拥有特殊名称的实例方法,这些名称是:

<	>	<=	>=	==	~
-	+	/	~/	*	%
|	ˆ	&	<<	>>>	>>
[]=	[]

但有些运算符,例如 !=,不在上述列表中,这些运算符不是实例方法,它们的行为是 Dart 内置的。

示例1:分数

下面以分数(Fraction)为例,来看看如何在类中定义操作符。

// ex451.dart
int gcd(int a, int b) { // 1
  while (b != 0) {
    (a, b) = (b, a % b);
  }
  return a;
}

class Fraction {
  Fraction(int num, int den) : assert(den != 0) { // 3
    final d = gcd(num, den);
    this.num = num ~/= d;
    this.den = den ~/= d;
  }

  late final int num; // 2 Numerator
  late final int den; // 2a Denominator

  Fraction operator +(Fraction f) => // 4
      Fraction(num * f.den + f.num * den, den * f.den);

  Fraction operator -(Fraction f) => // 4a
      Fraction(num * f.den - f.num * den, den * f.den);

  @override
  String toString() => den == 1 ? '$num' : '$num/$den'; // 5
}

void main() {
  var f1 = Fraction(3, 2); // 6
  var f2 = Fraction(2, 3);  // 6a
  assert("13/6" == (f1 + f2).toString()); // 7
  assert("5/6" == (f1 - f2).toString()); // 7a
}
  1. gcd 函数计算两个整数的最大公约数(最大公因数);
  2. num 代表分子,den 代表分母;
  3. Fraction 构造函数,自动进行约分操作;
  4. 使用关键字operator 加上 +/- 符号,定义分数的加/减法;分数加法公式为: \( \frac{b}{a} + \frac{d}{c} = \frac{bc+ad}{ac} \)
  5. Fraction的toString()方法,返回像 3/2(2分之3)这样的字符串;
  6. 声明分数变量 f1 (3/2)f2 (2/3);
  7. 分别计算 f1+f2f1-f2 并校验计算结果。

注意此例是如何使用 operator + 定义分数的加法的,可以将 operator + 整体想象成方法名 add,以方便理解语法。

注:为简洁起见,此例并未处理分子或分母是负数的情况。

示例2:num

Dart core中的 num 类定义的操作符:

part of dart.core;

sealed class num implements Comparable<num> {
  // ... (omitted for brevity)
  bool operator ==(Object other);
  num operator +(num other);
  num operator -(num other);
  num operator *(num other);
  num operator %(num other);
  double operator /(num other);
  int operator ~/(num other);
  num operator -();
  bool operator <(num other);
  bool operator <=(num other);
  bool operator >(num other);
  bool operator >=(num other);
  // ... (omitted for brevity)
}  

注:num 类中的操作符是抽象方法,意味着它们是由Dart VM(虚拟机)或 native code 实现的。

示例3:String

Dart core中的 String 类定义的操作符:

part of dart.core;

abstract final class String implements Comparable<String>, Pattern {
  // ... (omitted for brevity)
  String operator [](int index);
  bool operator ==(Object other);
  String operator +(String other);
  String operator *(int times);
  // ... (omitted for brevity)  
}

练习

请完善示例 ex451

  1. Fraction 支持分子或分母是负数;
  2. Fraction 添加乘(*)、除(/)操作符;
  3. main 函数数中,使用断言测试下新功能。

参考资料