集册 Rust 编程语言 通用函数调用语法

通用函数调用语法

欢马劈雪     最近更新时间:2020-08-04 05:37:59

305

ufcs.md
commit 024aa9a345e92aa1926517c4d9b16bd83e74c10d

有时,函数可能有相同的名字。就像下面这些代码:

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;

如果我们尝试调用b.f(),我们会得到一个错误:

error: multiple applicable methods in scope [E0034]
b.f();
  ^~~
note: candidate #1 is defined in an impl of the trait `main::Foo` for the type
`main::Baz`
    fn f(&self) { println!("Baz’s impl of Foo"); }
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: candidate #2 is defined in an impl of the trait `main::Bar` for the type
`main::Baz`
    fn f(&self) { println!("Baz’s impl of Bar"); }
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我们需要一个区分我们需要调用哪一函数的方法。这个功能叫做“通用函数调用语法”(universal function call syntax),这看起来像这样:

# 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::f(&b);
Bar::f(&b);

让我们拆开来看。

Foo::
Bar::

调用的这一半是两个traits的类型:FooBar。这样实际上就区分了这两者:Rust调用你使用的trait里面的方法。

f(&b)

当我们使用[方法语法](Method Syntax 方法语法.md)调用像b.f()这样的方法时,如果f()需要&self,Rust实际上会自动地把b借用为&self。而在这个例子中,Rust并不会这么做,所以我们需要显式地传递一个&b

尖括号形式(Angle-bracket Form)

我们刚才讨论的通用函数调用语法的形式:

Trait::method(args);

上面的形式其实是一种缩写。这是在一些情况下需要使用的扩展形式:

<Type as Trait>::method(args);
展开阅读全文