考慮以下 Dart 代碼:
class Vec2 {
num x, y;
Vec2(this.x, this.y);
Vec2 operator*(num rhs) => Vec2(x * rhs, y * rhs);
String toString() => "<$x, $y>";
}
void main() => print(Vec2(1, 2) * 3);
輸出如預期:
<3, 6>
但是,這僅在運算式的左側是 aVec2而右側是 a 時才有效num。在這種情況下,我希望乘法運算子是可交換的,所以我撰寫了以下擴展:
extension Vec2Util on num {
Vec2 operator*(Vec2 rhs) => Vec2(rhs.x * this, rhs.y * this);
}
人們可能自然希望以下代碼產生與第一個片段相同的輸出:
void main() {
num x = 3;
print("${x * Vec2(1, 2)}");
}
但是,編譯器反而報告The argument type 'Vec2' can't be assigned to the parameter type 'num'.它看起來好像編譯器num operator*(num rhs)在這種情況下將乘法決議為,然后抱怨 myVec2不能作為num運算元傳入。為什么編譯器顯然無視我的擴展?創建這樣的自定義交換運算子的正確方法是什么?
uj5u.com熱心網友回復:
你不能做你想做的事。
Dart 用戶可定義的二元運算子都是第一個運算元上的方法。Doinge1 e2有點像doing e1. (e2)where is the method 的名稱,除了你通常不能呼叫 method 。
為了能夠做到3 * vector,你需要方法是對的3。
您不能將方法添加到其他人的類,而不是擺弄他們的源代碼,并且int是一個系統類,所以即使這樣也是不可能的。
您不能使用擴展方法,因為當接收器型別已經具有同名的實體方法時,擴展方法不適用。并int定義所有運算子。(這就像,并且絕對不是巧合,用戶可定義的運算子是根據int需要選擇的。這在 Dart 中并不新鮮,運算子可以追溯到 C 和 Java。)
因此,您可以在 上定義擴展方法int,但無論如何都不能呼叫它,除非沒有覆寫:
extension MyInt on int {
Vector operator *(Vector other) => other.scalerMultiplication(this);
}
... MyInt(3) * vector ...
這比僅僅交換運算元更復雜。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/480531.html
