【问题标题】:Does dart support operator overloading? (not to be confused with overriding)dart 是否支持运算符重载? (不要与覆盖混淆)
【发布时间】:2020-05-29 08:57:38
【问题描述】:

这听起来与以下内容完全相同:Does dart support operator overloading
但是这个名字有误导性,问题是关于如何覆盖现有的操作符(== 操作符)。

据我了解,重载一个函数意味着有多个实现,这些实现仅在参数上有所不同,而在函数名上没有:

int max(int a, int b);
double max(double a, double b);

相比之下,重写意味着重写现有的实现。由于替换了原始功能,因此没有名称冲突。这在 OOP 中很常见,您可以扩展基类并覆盖其方法。

docs 表示存在可覆盖的运算符。所以我看到你可以实现自定义运算符。同时,dart 不支持重载方法。那么,dart 是否支持重载运算符?

能不能写出如下代码:

class Matrix{
  Matrix operator+(int b){//...};
  Matrix operator+(Matrix b({//...};
}

【问题讨论】:

标签: dart


【解决方案1】:

是的,您绝对可以这样做,但是您需要检查单个方法中的类型,因为一个运算符不能有重复的方法:

class Matrix {
  int num = 0;
  Matrix(this.num);
  Matrix operator+(dynamic b) {
    if(b is int) {
      return Matrix(this.num + b);  
    } else if(b is Matrix){
      return Matrix(this.num + b.num);
    } 
  }
}

void main() {
  print((Matrix(5) + 6).num);  

  print((Matrix(7) + Matrix(3)).num);
}

【讨论】:

  • 从技术上讲这不是超载。它仍然只是一个方法定义,里面有一个 hacky 开关。但这实际上对我有用,谢谢你的提示。
【解决方案2】:

您基本上已经回答了自己的问题。

有可覆盖的运算符。所以我看到你可以实现自定义运算符。同时,dart 不支持重载方法。那么,dart 是否支持重载运算符?

Dart 语言规范说:

10.1.1 运算符

运算符是具有特殊名称的实例方法。

Dart 不支持重载方法(或函数),运算符等价于方法,所以,Dart 不支持运算符重载。

【讨论】:

    【解决方案3】:

    加载 dartpad 后,dart 似乎不支持重载运算符:

    class A{
      operator*(int b){
        print("mul int");
      }
      operator*(double b){
        print("mul double");
      }
    }
    

    导致错误消息:

    Error compiling to JavaScript:
    main.dart:5:11:
    Error: '*' is already declared in this scope.
      operator*(double b){
    

    【讨论】:

    • 想补充一点,在 Dart 中创建联合类型的工作正在进行中,这将允许创建一个采用多种类型参数的方法:github.com/dart-lang/sdk/issues/4938。它仍然不是方法/运算符重载,但我会说这将是一个很好的解决方法。
    • 感谢问题链接。但这并不是很令人鼓舞,它已经开业将近 8 年了。我假设这将成为模式匹配/解构的草图支持的一部分。这将是一个巨大的语言变化。目前他们仍深陷nnbd。所以我敢打赌,至少需要一年的时间才能支持联合类型。
    【解决方案4】:

    geometry.dart 中有以下几行:

      /// Unary negation operator.
      ///
      /// Returns an offset with the coordinates negated.
      ///
      /// If the [Offset] represents an arrow on a plane, this operator returns the
      /// same arrow but pointing in the reverse direction.
      Offset operator -() => Offset(-dx, -dy);
    
    After some research it appears that `-` operator can be used with 0 or 1 parameter, which allows it to be defined twice.
    
      /// Binary subtraction operator.
      ///
      /// Returns an offset whose [dx] value is the left-hand-side operand's [dx]
      /// minus the right-hand-side operand's [dx] and whose [dy] value is the
      /// left-hand-side operand's [dy] minus the right-hand-side operand's [dy].
      ///
      /// See also [translate].
      Offset operator -(Offset other) => Offset(dx - other.dx, dy - other.dy);
    
    

    这只是因为- 运算符可以使用 0 或 1 个参数来定义。

    【讨论】:

      猜你喜欢
      • 2012-04-25
      • 2012-02-11
      • 2011-09-06
      • 1970-01-01
      • 1970-01-01
      • 2018-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多