我有结构Bar
来实现Foo
特征。
struct Bar;
trait Foo {
fn foo(&self) {
print!("Foo");
}
}
impl Foo for Bar {}
我还有Print
特征,它带有Kind
个参数。 Foo
和Bar
都Print
实施Bar
Kind
。
trait Print {
type Kind;
fn print(&Self::Kind);
}
impl Print for Bar {
type Kind = Bar;
fn print(_: &Bar) {
println!("Bar");
}
}
impl Print for Foo {
type Kind = Bar;
fn print(bar: &Bar) {
bar.foo();
Bar::print(bar);
}
}
最后,我想使用不同的实现来打印Bar
。
fn main() {
let b = Bar;
Bar::print(&b); // prints: Bar
Foo::print(&b); // prints: FooBar
<Bar as Foo>::print(&b); // error
}
该代码也可以playpen
的形式提供对print
的两个第一次调用工作正常但行<Bar as Foo>::print(&b);
给出了以下编译错误:
<anon>:35:5: 35:25 error: unresolved name `Foo::print`
<anon>:35 <Bar as Foo>::print(&b);
^~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
我原本期望最后两行打印相同的东西。为什么我会收到一条错误消息,指出Foo::print
是一个未解析的名称,当上面的行正常工作时?这两条线的区别是什么?
答案 0 :(得分:1)
<A as B>
是绝对的UFCS语法,意思是“找到类型B
的特征A
的实现”。然后,您的<Bar as Foo>::print
正尝试使用print
Foo
方法调用Bar
方法,Self
为Foo
。 <Foo as Print>::print
特征没有任何这样的方法,因此很自然地失败了。你需要的是Bar::print
。
Bar
首先查找类型print
上的内部方法,然后查找Bar
实现的任何特征上名为<Bar as Print>::print
的任何方法,并将其解析为{ {1}}。 Foo::Print
的交易相同。