演算子オーバーロード
Rustでは、ほとんどの演算子がトレイトによってオーバーロードできます。つまり、いくつかの演算子は
引数によって違う操作を行うことができます。これは、演算子がメソッド呼び出しの糖衣構文だからこそ
実現できます。例えば、a + bの+演算子はaddメソッドをa.add(b)のように呼び出します。
このaddメソッドはAddトレイトによって定義されていないため、+演算子はAddトレイトを
実装すれば使えるようになります。
Addのような、演算子オーバーロードに使うトレイトの一覧はcore::opsにあります。
use std::ops; struct Foo; struct Bar; #[derive(Debug)] struct FooBar; #[derive(Debug)] struct BarFoo; // `std::ops::Add`トレイトは`+`演算子の動作を定義するのに使います。 // ここでは、右辺値が`Bar`のときの足し算を定義する`Add<Bar>`を実装します。 // このブロックはFoo + Bar = FooBarを実装しています。 impl ops::Add<Bar> for Foo { type Output = FooBar; fn add(self, _rhs: Bar) -> FooBar { println!("> Foo.add(Bar) was called"); FooBar } } // 型を逆にすることで、交換法則に従わない実装を作ることができます。 // ここでは、右辺値が`Foo`のときの足し算を定義する`Add<Foo>`を実装します。 // このブロックはBar + Foo = BarFooを定義しています。 impl ops::Add<Foo> for Bar { type Output = BarFoo; fn add(self, _rhs: Foo) -> BarFoo { println!("> Bar.add(Foo) was called"); BarFoo } } fn main() { println!("Foo + Bar = {:?}", Foo + Bar); println!("Bar + Foo = {:?}", Bar + Foo); }