为什么编译器说调用在关联类型中是不明确的,而事实并非如此?

问题描述

此代码:

trait SayHello {
    fn say_hello() { println!("hello") }
}

trait Foo {
    type Hello: SayHello;
}

trait Bar: Foo {
    type Hello: SayHello;
}

struct Generic<T>(T);

impl<T> Generic<T> where T: Bar<Hello = <T as Foo>::Hello> {
    fn say_hello() {
        T::Hello::say_hello()
    }
}

返回此错误:

error[E0221]: ambiguous associated type `Hello` in bounds of `T`
  --> src/lib.rs:17:9
   |
6  |     type Hello: SayHello;
   |     --------------------- ambiguous `Hello` from `Foo`
...
10 |     type Hello: SayHello;
   |     --------------------- ambiguous `Hello` from `Bar`
...
17 |         T::Hello::say_hello()
   |         ^^^^^^^^^^^^^^^^^^^ ambiguous associated type `Hello`
   |
help: use fully qualified syntax to disambiguate
   |
17 |         <T as Foo>::Hello()
   |         ^^^^^^^^^^^^^^^^^
help: use fully qualified syntax to disambiguate
   |
17 |         <T as Bar>::Hello()
   |         ^^^^^^^^^^^^^^^^^

但不应该有任何歧义。明确指出HelloFoo 中的bar 关联类型相同。

  • 为什么会出现问题?
  • 有没有办法让这个逻辑起作用?

解决方法

如果 T 实现了 Bar,它也必须实现 Foo,根据您对 trait 的限制。因此,T::Hello 中的 say_hello() 可以同时指代 <T as Foo>::Hello<T as Bar>::Hello,它们修复了您的示例。

可以引入另一个参数 H: SayHello 并将 Foo::HelloBar::Hello 设置为 H。分派到 say_hello() 然后通过 H::say_hello() 而不是 T::Hello::say_hello() 工作。

struct Generic<T>(T);

impl<T,H> Generic<T> where T: Bar<Hello=H> + Foo<Hello=H>,H: SayHello {
    fn say_hello() {
        H::say_hello()
    }
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=920368d7c2d4e5eea98465de8b193b9e

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...