指定Type(<type as =“”trait =“”>)</type>时Trait的未解析名称

时间:2015-03-27 16:16:57

标签: rust

我有结构Bar来实现Foo特征。

struct Bar;

trait Foo {
    fn foo(&self) {
        print!("Foo");
    }
}

impl Foo for Bar {}

我还有Print特征,它带有Kind个参数。 FooBarPrint实施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是一个未解析的名称,当上面的行正常工作时?这两条线的区别是什么?

1 个答案:

答案 0 :(得分:1)

<A as B>是绝对的UFCS语法,意思是“找到类型B的特征A的实现”。然后,您的<Bar as Foo>::print正尝试使用print Foo方法调用Bar方法,SelfFoo<Foo as Print>::print特征没有任何这样的方法,因此很自然地失败了。你需要的是Bar::print

Bar首先查找类型print上的内部方法,然后查找Bar实现的任何特征上名为<Bar as Print>::print的任何方法,并将其解析为{ {1}}。 Foo::Print的交易相同。