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__
).
1 Answer
Reset to default 2No.
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.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745155070a4614067.html
*
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:19MyClass() * 2
works, but2 * MyClass()
givesError: A value of type 'MyClass' can't be assigned to a variable of type 'num'
. – user200783 Commented Feb 23 at 15:27int
class, which is not possible. If you expect anint
result, you might be able to overload the cast-to-int operator inMyClass
(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:35MyClass
to anint
first before applying the*
* operator to that. – Frank van Puffelen Commented Feb 23 at 16:38