Syntax and Semantics
Universal Function Call Syntax
別々のtraitが同名の関数を持っていることがありますね。
fn main() {
trait Foo {
fn f(&self);
}
trait Bar {
fn f(&self);
}
struct Baz;
impl Foo for Baz {
fn f(&self) { println!("Baz’s impl of Foo"); }
}
impl Bar for Baz {
fn f(&self) { println!("Baz’s impl of Bar"); }
}
let b = Baz;
}FooとBarというtraitがともにf()メソッドをもっていて、
それらをBazstructにimplしました。
これだけではエラーにはなりませんが、b.f()を呼ぶとエラーです。
b.f(); // Errorこれはシグネチャが違っていても(Barのf()がf(&self, i32)とかでも)、
コンパイルエラーになるようです。
それで、どうにかして曖昧さをなくさないといけないのですが、 ‘universal function call syntax’を使えば可能です。
Syntaxは以下のように、
Foo::f(&b);
Bar::f(&b);C++の名前空間みたいにtraitを指定します。
b.f()のようなメソッド呼び出しとは違い、&bは明示的に渡さなければいけません。
Angle-bracket Form
実はこの’universal function call syntax’は、 ‘Angle-bracket form’の短縮版らしいです。 Angle-bracket formは、
<Type as Trait>::method(args);のようなsyntaxで記述します。
TypeにimplされているTraitがもつmethodを呼ぶ、ということですね。
trait Foo {
fn clone(&self);
}
#[derive(Clone)]
struct Bar;
impl Foo for Bar {
fn clone(&self) {
println!("Making a clone of Bar");
<Bar as Clone>::clone(self);
}
}上のように使えますが、Clone::clone(self)でも大丈夫なようです。
どっちでもいいということでしょうか。