2017-07-02 110 views
2

我剛剛開始學習來自Java/JavaScript背景的Rust,所以請耐心等待,因爲我明顯錯過了我對生命時間的理解。我在生命中缺少什麼?

fn main() { 
    struct Appearance<'a> { 
     identity:  &'a u64, 
     role:   &'a str 
    }; 
    impl<'a> PartialEq for Appearance<'a> { 
     fn eq(&self, other: &Appearance) -> bool { 
      self.identity == other.identity && self.role == other.role 
     } 
    }; 
    let thing = 42u64; 
    let hair_color = "hair color"; 
    let appearance = Appearance { 
     identity: &thing, 
     role: &hair_color 
    }; 
    let another_thing = 43u64;  
    let other_appearance = Appearance { 
     identity: &another_thing, 
     role: &hair_color 
    }; 
    println!("{}", appearance == other_appearance); 
} 

,因爲編譯器到達other_appearance,告訴我,another_thing不活足夠長的時間這是給我一個編譯錯誤。但是,如果我省略other_appearance的創建,程序編譯並運行正常。爲什麼我得到這個錯誤?

回答

5

PartialEq trait有一個類型參數,用於指定右側的類型。既然你沒有指定它,它默認爲與左側相同的類型。這意味着雙方被認爲具有相同的壽命。 這會導致錯誤,因爲another_thingappearance之前丟失,但other_appearance(保留對another_thing的引用)假定與appearance的壽命相同。

您可以通過在右手側的不同生命週期解決這個問題:

impl<'a, 'b> PartialEq<Appearance<'b>> for Appearance<'a> { 
    fn eq(&self, other: &Appearance<'b>) -> bool { 
     self.identity == other.identity && self.role == other.role 
    } 
}; 
+0

這實際上很有趣,因爲'#[derive(PartialEq)]'創建的實例與OP的問題相同。 –

+0

另一方面,由於這些值按照與它們聲明相反的順序被刪除,所以也可以通過交換順序來解決這個問題,即使用'other_appearance == appearance'而不是'appearance == other_appearance'。是的,Rust有幾個疣子... –

+0

謝謝!我需要詳細說明語法,即使我在概念上理解你所說的:) –

1

這與使用==語法結合糖時的終生推理/差異似乎是一個問題 - 請注意,替換與PartialEq::eq(&appearance, &other_appearance)工作的比較。我不知道這是否是一個已知的錯誤。

+0

奇怪。這一定是一個錯誤。而且這是特別令人驚訝的,因爲當你''[派生(PartialEq)]'時,行爲與OP的行爲相同,這讓我想知道它以前怎麼沒有被發現。 –