最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

In Dart, can I implement `operator *` as in `2 * MyClass()`? - Stack Overflow

programmeradmin2浏览0评论

In Dart, I can implement operator * that is called when someone writes MyClass() * 2:

class MyClass {
  String operator * (int rhs){
    return 'MyClass * int';
  }
}

Is it possible to write a similar operator that is called for 2 * MyClass()?

(For example in Python, the former is done by implementing __mul__ and the latter by __rmul__).

In Dart, I can implement operator * that is called when someone writes MyClass() * 2:

class MyClass {
  String operator * (int rhs){
    return 'MyClass * int';
  }
}

Is it possible to write a similar operator that is called for 2 * MyClass()?

(For example in Python, the former is done by implementing __mul__ and the latter by __rmul__).

Share Improve this question asked Feb 23 at 12:28 user200783user200783 14.4k15 gold badges79 silver badges142 bronze badges 5
  • It looks like in Dart 3 you can overload * in your own class (see page 37 of the language spec: spec.dart.dev/DartLangSpecDraft.pdf). What isn't working about your code? --- A good source for example code: medium/@hamxa678/operator-overloading-in-dart-517dde92e23d – Frank van Puffelen Commented Feb 23 at 15:19
  • @FrankvanPuffelen > "What isn't working about your code?" - MyClass() * 2 works, but 2 * MyClass() gives Error: A value of type 'MyClass' can't be assigned to a variable of type 'num'. – user200783 Commented Feb 23 at 15:27
  • 1 Ah, yeah... now I get it. That'd indeed require you to overload the * operator in the int class, which is not possible. If you expect an int result, you might be able to overload the cast-to-int operator in MyClass (I don't immediately see an example of it), and then the * on int will perform the multiplication. – Frank van Puffelen Commented Feb 23 at 16:35
  • From a quick search it seems implicit casts can not be overloaded in Dart. stackoverflow/questions/16950515/… and stackoverflow/questions/49541914/…. So you'd have to explicitly convert MyClass to an int first before applying the ** operator to that. – Frank van Puffelen Commented Feb 23 at 16:38
  • 1 Important to keep in mind that the operators, despite looking commutative, are all unidirectional. For <a> OP <b>, we look in a's class for an OP method only. b's class is not even considered, except that it must match the signature for the OP method of a's class. – Randal Schwartz Commented Feb 23 at 20:04
Add a comment  | 

1 Answer 1

Reset to default 2

No.

Dart does not have overloading, and the int class already has a num operator *(num other) method.

And (most) binarly operators are just methods with special names and calling syntax, they're declared on the left operand. Invocation is not symmetric.

That means there is nothing you can do to change what 2 * something means. It can only mean one thing, and it already does. It will always invoke int.operator * with something, which must then be of type num.

You need to do something to the 2 to change its behavior, or the *.

You can do:

extension ScaleMyClass on int {
  MyClass mul(MyClass other) => other * this;
}
///
  var scaled = 2.mul(myClassInstance);

Not as nice. Also doesn't work well if multiple classes want to be scalable.

Then you could also just use another short operator-like syntax that isn't used by int already - which is really only [] and (), all the binary operators are defined for int. (It's almost like operators were added to the C language until all the int operations were possible, and then it stopped. The languages in the C syntax family just inherited those.) I'd go with function invocation:

extension IntScaleMyClass on int {
  MyClass call(MyClass other) => other * this;
}
// ...
  var scaled = 2(myClassInstance);

Or you can convert int to another (probably extension) type with other members:

extension type const MyClassFactor(int _) {
  MyClass operator *(MyClass other) => other * _;
}
extension ToScale on int {
  MyClassFactor get scale => MyClassFactor(this);
}
// ...
  var scaled = 2.scale * myClassInstance;

Then you are using *, but not directly on int.

But nothing you can possibly do to make 2 * myClassInstance work, it already means something else, and you can't change that.

发布评论

评论列表(0)

  1. 暂无评论