这是演示问题的玩具代码:
trait Foo {}
trait Boo<T> {
fn f() -> T;
}
impl<T> Boo<T> for i32
where
T: Foo,
{
fn f() -> T {
unimplemented!();
}
}
impl<'a, T> Boo<&'a T> for i32
where
T: Foo,
{
fn f() -> T {
unimplemented!();
}
}
Run Code Online (Sandbox Code Playgroud)
我想有两个通用实现trait Boo,但它不编译:
error[E0119]: conflicting implementations of trait `Boo<&_>` for type `i32`:
--> src/main.rs:16:1
|
7 | / impl<T> Boo<T> for i32
8 | | where
9 | | T: Foo,
10 | | {
... |
13 | | }
14 | | }
| |_- first implementation here
15 |
16 | / impl<'a, T> Boo<&'a T> for i32
17 | | where
18 | | T: Foo,
19 | | {
... |
22 | | }
23 | | }
| |_^ conflicting implementation for `i32`
|
= note: downstream crates may implement trait `Foo` for type `&_`
Run Code Online (Sandbox Code Playgroud)
我不打算将这部分功能用于其他板条箱.我试过了:
modpub(crate) 一切都没有成功.
反正有没有给编译器一个提示,它不应该关心任何人将实现Foo任何引用?
也许我的玩具示例不是最好的,所以这里是真正的代码.它用于与我程序的C部分集成,所以它有点复杂.
impl<T: MyTrait> MyFrom<Option<T>> for *mut c_void {
fn my_from(x: Option<T>) -> Self {
match x {
Some(x) => <T>::alloc_heap_for(x),
None => ptr::null_mut(),
}
}
}
impl<'a, T: MyTrait> MyFrom<Option<&'a T>> for *mut c_void {
fn my_from(x: Option<&'a T>) -> Self {
match x {
Some(x) => x as *const T as *mut c_void,
None => ptr::null_mut(),
}
}
}
Run Code Online (Sandbox Code Playgroud)
这里的冲突与后一个实现的引用性没有任何关系。问题是,在第一个实现中,T可以是任何类型,包括引用类型。假设您进行以下函数调用:
let x: i32 = 10;
let result: &u8 = x.f();
Run Code Online (Sandbox Code Playgroud)
此时,类型解析器需要弄清楚正在调用什么函数。它发现一个冲突的实现:
impl Boo<&u8> for i32 via Boo<T> (T == &u8),
impl Boo<&u8> for i32 via Boo<&T> (T == u8),
Run Code Online (Sandbox Code Playgroud)
如果您在后一个实现中使用具体类型,您会遇到完全相同的问题:
impl Boo<&u8> for i32 via Boo<T> (T == &u8),
impl Boo<&u8> for i32 via Boo<&T> (T == u8),
Run Code Online (Sandbox Code Playgroud)
这种冲突意味着编译器不能允许这两种实现共存。
您在这里想要做的具体事情称为“专业化”;它指的是一组规则的提案,该提案表示,如果其中一个实现明显比另一个更“具体”,则允许存在这样的重叠实现,在这种情况下,编译器将选择更具体的实现。这被跟踪为RFC #1210。
| 归档时间: |
|
| 查看次数: |
196 次 |
| 最近记录: |