2017-07-02 2 views
2

Ich habe gerade begonnen, Rust zu lernen, aus einem Java/JavaScript-Hintergrund, also ertragen Sie mit mir, weil ich offensichtlich etwas in meinem Verständnis von Lebenszeiten vermisse.Fehle ich etwas, wenn es um Lebenszeiten geht?

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); 
} 

Das gibt mir einen Übersetzungsfehler wie der Compiler die other_appearance erreicht hat, mir zu sagen, dass another_thing nicht lange genug lebt. Wenn ich jedoch die Erstellung von other_appearance weglassen, kompiliert das Programm und läuft gut. Warum erhalte ich diesen Fehler?

Antwort

5

Die Eigenschaft PartialEq hat einen Typparameter, der den Typ der rechten Seite angibt. Da Sie es nicht angegeben haben, wird standardmäßig derselbe Typ wie auf der linken Seite verwendet. Dies bedeutet, dass beide Seiten die gleiche Lebensdauer haben. Dies führt zu einem Fehler, da another_thing vor appearance verworfen wird, aber other_appearance (enthält einen Verweis auf another_thing) wird als dieselbe Lebensdauer wie appearance angenommen.

Sie können dieses Problem beheben, indem Sie eine andere Lebensdauer auf der rechten Seite mit:

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

Das ist eigentlich interessant, weil die Instanz, die von '# [derived (PartialEq)]' erzeugt wird, das gleiche Problem hat wie OPs. –

+0

Da die Werte in der umgekehrten Reihenfolge fallen, in der sie deklariert werden, können Sie dies auch beheben, indem Sie die Reihenfolge vertauschen, d. H. 'Other_apperance == aussehen 'anstelle von' aussehen == other_apperance'. Ja, Rust hat ein paar Warzen ... –

+0

Danke! Ich muss mich auf die Syntax konzentrieren, auch wenn ich konzeptionell verstehe, was du gesagt hast :) –

1

Dies scheint ein Problem mit Lifetime-Inferenz/Varianz zu sein, wenn mit der == Syntax Zucker kombiniert - beachten Sie, dass das Ersetzen des Vergleichs mit PartialEq::eq(&appearance, &other_appearance) funktioniert. Ich weiß nicht, ob das ein bekannter Bug ist.

+0

Schräge. Dies muss ein Fehler sein. Und es ist besonders überraschend, denn das Verhalten ist das gleiche wie bei OPs, wenn Sie stattdessen "# [abgeleitete (PartialEq)]" verwenden, was mich wundern lässt, wie es zuvor noch nicht gefunden wurde. –

Verwandte Themen