2016-06-01 3 views
0

diese Struktur BetrachtenHashwert von zwei Objekten mit unterschiedlichen Eigenschaften ist die gleiche

struct Node : Hashable { 
let value : Int 
let i : Int 
let j : Int 

init(withValue val : Int, position : (Int,Int)){ 
    value = val 
    self.i = position.0 
    self.j = position.1 
} 

var hashValue: Int { 
    return "\(value),\(i),\(j)".hashValue 
} 
} 

Mein == Betreiber

func ==(left: Node, right: Node) -> Bool { 
    return left.hashValue == right.hashValue 
} 

Wenn ich erstellen 2 Knoten:

let node1 = Node(withValue: 1260, position: (8,694)) 
let node2 = Node(withValue: 33, position: (257,286)) 

und vergleichen sie:

node1 == node2 //true ??? 

Warum funktioniert die hashValue Funktion nicht wie erwartet?

Sollte es auf eine andere Art und Weise implementiert werden?

Counter Frage: Wenn ja, was ist der richtige Weg, HashValue für diese Art von Objekt zu berechnen?

Mehr Infos

Als ich das debuggt:

(lldb) po node1.hashValue 
4799450060528192039 

(lldb) po node2.hashValue 
4799450060528192039 
+2

Wo Ihre init-Methode ist? –

+0

Entschuldigung, vergessen zu kopieren: D Jetzt hinzugefügt! – prad

+1

http://stackoverflow.com/questions/31438210/how-to-implement-the-hashable-protocol-in-swift-for-an-int-array-a-custom-strin – oremag14jf

Antwort

3

Equal Hash-Werte nicht gleich ursprünglichen Werte garantieren. Das gesamte Konzept der hash collisions besteht nur aus diesem Grunde:

In der Informatik einer Kollision oder Zusammenstoß ist eine Situation, die auftritt, wenn zwei verschiedene Stücke von Daten, die den gleichen Hash-Wert haben ...

Kollisionen sind unvermeidlich, wenn Mitglieder einer sehr großen Menge (wie alle möglichen Personennamen oder alle möglichen Computerdateien) auf eine relativ kurze Bitfolge abgebildet werden.

Es bedeutet, dass diese Implementierung von == Betreiber falsch ist:

func ==(left: Node, right: Node) -> Bool { 
    return left.hashValue == right.hashValue 
} 

Stattdessen sollte es sein:

func ==(left: Node, right: Node) -> Bool { 
    return left.value == right.value 
     && left.i == right.i 
     && left.j == right.j 
}