簡體   English   中英

為引用和非引用類型實現特征會導致實現沖突

[英]Implementing a trait for reference and non reference types causes conflicting implementations

我正在嘗試創建一個特征並為所有非引用類型提供一個實現,並為所有引用類型提供另一個實現。

這無法編譯:

trait Foo {}
impl<T> Foo for T {}
impl<'a, T> Foo for &'a mut T {}

這失敗了,錯誤

error[E0119]: conflicting implementations of trait `Foo` for type `&mut _`:
 --> src/main.rs:3:1
  |
2 | impl<T> Foo for T {}
  | -------------------- first implementation here
3 | impl<'a, T> Foo for &'a mut T {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&mut _`

奇怪的是,這有效:

trait Bar {}

impl<T> Bar for T
where
    T: Clone,
{}

impl<'a, T> Bar for &'a mut T
where
    T: Clone + 'static,
{}

為什么具有Clone約束的版本有效,如何在沒有它的情況下使其工作?

正如您所了解的那樣,通用T可以是任何¹,因此只要第一個impl中的T&'a mut UFoo就會重疊(沖突),因為第二個impl也涵蓋了這種情況(當TU )。

Clone版本的工作原理只是因為&mut引用永遠不會實現Clone ,因此T where T: Clone之間沒有重疊, T where T: Clone&'a mut T T.2。如果你試圖為不可變( & )引用實現Bar ,你將再次發生沖突,因為不可變引用確實實現了Clone

如果沒有它,我可以讓它工作嗎?

如果用“it”表示引用類型的一個實現,而另一個用於非引用類型的實現,則在Rust中不可能出於同樣的原因,你不能為struct s實現一種特性,而另一種方式用於enum :根本沒有辦法表達它(在當前的Rust中)。

一個可能適合您的常見模式是為您需要的任何非引用類型單獨實現您的特征,然后添加“覆蓋impl”,其涵蓋對已經實現特征的類型的任何引用,例如:

impl Foo for u32 { ... }
impl Foo for i32 { ... }
impl<'a, T> Foo for &'a T where T: Foo + 'a { ... }
impl<'a, T> Foo for &'a mut T where T: Foo + 'a { ... }

¹嗯,任何Sized東西,至少。 你必須添加?Sized如果這不是你想要的。

² where T: Clone + 'static子句無關緊要,因為&'a mut T將永遠無法Clone無論T本身是否存在。

Clone版本工作的原因是因為實現特征的類型不再在實現上發生沖突。

以第一個示例為例,添加默認實現。

trait Foo {
    fn hi(&self){
        println!("Hi");
    }
}

然后我們impl<T> Foo for T {}使用impl<T> Foo for T {} Foo為所有類型T實現Foo ,這實際上足以讓我們使用對類型的引用並使用Foo特征。 例如:

fn say_hi<'a>(b: &'a mut Foo){
    b.hi();
}

fn main(){
    let mut five = 5;

    five.hi(); // integer using Foo
    say_hi(&mut five); // &'a mut Foo
}

為了回答你問題的第二部分,你不需要第二個實現impl<'a,T> Foo for &'a mut T {}因為impl<T> Foo for T {} impl<'a,T> Foo for &'a mut T {} impl<T> Foo for T {}足以給你什么你在找。

現在我們已經看到第一個示例在沒有第二個實現的情況下工作,它開始有意義,使用Clone的示例有效,因為您正在實現類型T的子集,它們是Clone和不同的類型子集&'a mut T Clone+static

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM