【问题标题】:Unresolved name for Trait when specifying the Type (<Type as Trait>)指定类型时未解析的特征名称 (<Type as Trait>)
【发布时间】:2015-03-27 16:16:56
【问题描述】:

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

struct Bar;

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

impl Foo for Bar {}

我也有 Print 特征,它采用 Kind 参数。 FooBar 都实现了 PrintBar 作为其 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
}

代码也可以在playground中找到

print 的两次第一次调用工作正常,但&lt;Bar as Foo&gt;::print(&amp;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 是一个未解析的名称?这两行有什么区别?

【问题讨论】:

  • 我本来希望 Bar::print 由于歧义而出错...也许你发现了一个错误?
  • @ker:为什么? Bar::print 一点也不含糊。
  • 这个问题的关联类型部分完全是一条红鲱鱼。
  • @ChrisMorgan:现在从问题中删除了关联类型。谢谢
  • @ker:“Print on Foo on Bar”不是一回事。 impl Print for Foo 是对未调整大小的类型 Foo 的实现——也就是说,&amp;self&amp;Foo 类型,一个特征对象。如果一个人想要为所有实现Foo的类型实现Print,那将是impl&lt;T: Foo&gt; Print for T,并且由于特征一致性规则而无法编译。

标签: rust


【解决方案1】:

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

Bar::print 首先在 Bar 类型上查找内部方法,然后在 Bar 实现的任何 trait 上查找名为 print 的任何方法,因此被解析为 &lt;Bar as Print&gt;::printFoo::Print 的处理方式相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-31
    • 1970-01-01
    • 2012-04-23
    相关资源
    最近更新 更多