指定类型时特征的未解析名称 (<Type as Trait>)

Unresolved name for Trait when specifying the Type (<Type as Trait>)

我有一个实现 Foo 特性的结构 Bar

struct Bar;

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

impl Foo for Bar {}

我还有 Print 特征,它采用 Kind 参数。 FooBar 都以 Bar 作为其 Kind 实现 Print

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
}

代码也可以在 playground

print 的两次调用工作正常,但行 <Bar as Foo>::print(&b); 给出了以下编译错误:

error[E0576]: cannot find method or associated constant `print` in trait `Foo`
  --> src/main.rs:35:19
   |
35 |     <Bar as Foo>::print(&b); // error
   |                   ^^^^^ not found in `Foo`

我本以为最后两行打印的是同样的东西。为什么我会收到一条错误消息,指出 Foo::print 是一个未解析的名称,而上面的行运行正常?这两行有什么区别?

<A as B>Fully Qualified Syntax (FQS) 意思是“找到 A 类型的特征 B 的实现”。那么,您的 <Bar as Foo>::print 正试图从 Foo 特征调用 print 方法,BarSelfFoo trait 没有任何这样的方法,所以它很自然地失败了。你需要的是 <Foo as Print>::print.

Bar::print 首先在类型 Bar 上查找内部方法,然后在 Bar 实现的任何特征上查找任何名为 print 的方法,这样就解决了作为 <Bar as Print>::printFoo::Print.

的交易相同