dart支持运算符重载吗

q3qa4bjr  于 2023-01-06  发布在  其他
关注(0)|答案(6)|浏览(169)

我读到Dart不支持函数重载。它支持运算符重载吗?如果支持,你能用一个简单的例子告诉我它是怎么做的吗?有什么优点吗?

4ktjp1zp

4ktjp1zp1#

当你在新版本中使用==操作符重载时,你选择的答案不再有效。现在你需要做的是:

class MyClass {
  @override
  bool operator ==(other) {
    // compare this to other
  }
}

但这样做不安全。other未指定为类型,可能会发生意外情况。例如:

void main() {
  var a = A(1);
  var b = B(1);
  var result = a == b;
  print(result); //result is true
}

class A {
  A(this.index);

  final int index;

  @override
  bool operator ==(other) => other.index == index;
}

class B {
  B(this.index);

  final int index;
}

所以你可以这样做:

class A {
  A(this.index);

  final int index;

  @override
  bool operator ==(covariant A other) => other.index == index;
}

您需要使用covariant。因为Object重载了==运算符。

或者你可以

测试对象类型:
访视:hash_and_equals

class A {
  A(this.index);

  final int index;

  @override
  bool operator ==(other) => other is A && (other.index == index);

  @override
  int get hashCode => index;
}
vi4fp9gy

vi4fp9gy2#

Dart不支持使用operator关键字后跟要重载的运算符的运算符重载。以下示例为MyClass对象重载**==**运算符:

class MyClass {
  operator ==(MyClass other) {
    // compare this to other
  }
}

几乎所有的Dart内置操作符都可以重载,只有几个值得注意的例外,即赋值操作符**=和引用等价操作符==(不再存在)。
至于运算符重载的优点,它允许您重用具有众所周知的语义含义的运算符,如
==+,用于对象上的运算。例如,如果您有一个Matrix类重载了+运算符,那么您可以使用语法m1 + m2添加两个矩阵,而不是使用更麻烦的m1.plus(m2)**

bogh5gae

bogh5gae3#

为了扩展Lars的答案,还可以使用内联函数语法重载运算符。

class MyClass {
  operator ==(MyClass o) => id == o.id;
}
798qvoo8

798qvoo84#

学习如何使用运算符重载的一个令人惊奇的例子是在dart中处理复数的类:

import 'dart:core';

class Complex {
  final double real;
  final double imaginary;

  Complex({this.real = 0, this.imaginary = 0});

  Complex.ri(this.real, this.imaginary);

  Complex operator +(Complex b) {
    return Complex(
        real: this.real + b.real, imaginary: this.imaginary + b.imaginary);
  }

  Complex operator -(Complex b) {
    return Complex(
        real: this.real - b.real, imaginary: this.imaginary - b.imaginary);
  }

  Complex operator *(Complex b) {
    return Complex(
        real: this.real * b.real - this.imaginary * b.imaginary,
        imaginary: this.real * b.imaginary + this.imaginary * b.real);
  }

  Complex operator /(Complex b) {
    // https://stackoverflow.com/a/41146661/6846888
    var conjugation = b.conjugate();
    var denominatorRes = b * conjugation;

    // denominator has only real part
    var denominator = denominatorRes.real;
    var nominator = this * conjugation;

    return Complex(
        real: nominator.real / denominator,
        imaginary: nominator.imaginary / denominator);
  }

  bool operator ==(b) {
    return b.real == this.real && b.imaginary == this.imaginary;
  }

  @override
  String toString() {
    return 'Complex(real: ${real}, imaginary: ${imaginary})';
  }
}
vwhgwdsa

vwhgwdsa5#

从Dart 2.7版开始,您可以向现有类添加运算符,例如:

extension Contains on String {
  bool operator <<(Pattern other) => contains(other);
  bool operator >>(String other) => other.contains(this);
}
nom7f22z

nom7f22z6#

使用复数作为示例,我可以实现“Complex * num”,如下所示:

Complex operator *(dynamic b) {
  if (b is Complex) {
    return Complex( real: ... );
  } else if (b is num) {
    return Complex.ri(real*b, imaginary*b);
  }
}
...

但是如何实现“num * Complex”呢?可能吗?

相关问题