2015-08-05 8 views
7

Ich habe zwei eigene Klassen A und B und möchte eine HashMap verwenden. Ich habe einen Code wie folgt:Wie implementiert Eq und Hash für meine eigenen Strukturen, um sie in HashMap zu verwenden?

use std::collections::HashMap; 

pub struct A 
{ 
    x: i32, 
    y: i32, 
    title: String, 
    b_obj: B, 
} 

pub struct B 
{ 
    a: u32, 
    b: u32, 
    a_obj: A, 
} 

fn main() 
{ 
    let map = HashMap::new(); 
    map.insert(A{x: 10, y: 20, title: "test".to_string()}, B{a: 1, b: 2}); 
} 

Aber der Compiler gibt mir diese Fehler:

error: the trait core::cmp::Eq is not implemented for the type A [E0277]
error: the trait core::hash::Hash is not implemented for the type A [E0277]

Ich weiß, dass ich diese Eigenschaften implementieren müssen, aber nach Stunden der Internet-Suche habe ich nichts gefunden, über die Implementierung Sie.
Bitte, geben Sie mir ein Beispiel, wie man das macht.

Bearbeiten: Eigentlich ist mein Code komplizierter und meine Strukturen enthalten andere Strukturen (Ich habe Code bearbeitet). Und Compiler beschweren sich, dass ich Gl.

Die Hash-Eigenschaft, die ich implementiert habe. Es scheint jetzt so richtig. Meine Implementierung ist wie folgt:

impl Hash for Application { 
    fn hash<H>(&self, state: &mut H) where H: Hasher { 
    state.write_u32(self.pid); 
     state.finish(); 
    } 
} 

ich eine impl für PartialEq auch gemacht:

impl PartialEq for Application { 
    fn eq(&self, other: &Application) -> bool { 
    self.pid == other.pid 
    } 
} 

Aber der Compiler über Eq beschwert:

error: the trait core::cmp::Eq is not implemented for the type app::Application

Wie kann ich Gl implementieren? ?? Warum gibt es keine Implementierung in den Dokumenten?

+0

Ihre Strukturen sind gegenseitig rekursiv, jeder enthält ein Feld des anderen Typs nach Wert. Dies kann nicht so wie es ist kompiliert werden. – barjak

+1

Ich denke, dein Impl von 'Hash' sollte einfach' self.pid.hash (state) 'sein. Für mich ist es ein Fehler, 'Finish' zu nennen. – barjak

Antwort

3

Eq ist das, was wir ein Markermerkmal nennen: es hat keine Methode für sich, es ist nur eine Möglichkeit für den Programmierer auszudrücken, dass seine Struktur eine bestimmte Eigenschaft verifiziert. Sie können es wie folgt implementieren:

impl Eq for Application {} 

Oder alternativ verwenden #[derive(Eq)] oben auf der Anwendungs ​​Erklärung.

Eq ist ein Merkmal, das an PartialEq gebunden ist. Dies bedeutet, dass Sie es nur auf Strukturen implementieren können, die auch PartialEq implementieren (was hier der Fall ist). Durch Implementierung von machen Sie das Versprechen, dass Ihre Implementierung von PartialEq reflexiv ist (siehe die Dokumentation für das, was es bedeutet).

+0

danke. Ich denke, das muss irgendwo in der Dokumentation sein. – Revertron

+0

Tatsächlich sollte es im API-Dokument einige Beispiele für 'Eq' und' ParialEq' geben. Ich werde versuchen, bald etwas hinzuzufügen. – barjak

4

Sie können den Compiler ableiten für Sie, diese Instanzen durch die folgende vor Ihrer Strukturdeklaration einfügen:

#[derive(PartialEq, Eq, Hash)] 
pub struct A 
    ... 

Sie natürlich manuell stattdessen implementieren könnte. Wenn Sie das tun möchten, sollten Sie die Dokumentation zu traits, Eq und Hash lesen.

+2

die Frage ist, wie man eigene Implementierung von Hash schreiben? – Revertron

+2

es gibt selten einen Grund, dies zu tun ... Aber wie @fjh schrieb, wenn Sie wissen, welche Eigenschaft zu implementieren, suchen Sie die Dokumentation. Wenn Sie Probleme haben, geben Sie den Code ein, den Sie versucht haben. –

Verwandte Themen