2014-06-16 7 views
23

w Objective-C (i innych języków) to stosunkowo dobry domyślny realizacja - (NSUInteger)hash może być:Napisanie dobrego Hashable wdrożenie w Swift

- (NSUInteger)hash { 
    return 31u * [self.property1 hash] + [self.property2 hash]; 
} 

Zakładając zarówno property1 i property2 powrotne dobre wartości dla hash.

Nie działa to w równoważnej metodzie Swift'a var hashValue: Int zdefiniowanej w protokole Hashable.

Równoważny kod Swift prawdopodobnie się przepełni, a to jest błąd runtime w Swift.

var hashValue: Int { 
    return 31 * property1.hashValue + property2.hashValue // overflow-tastic 
} 

Więc moje pytanie brzmi, jaka jest najlepsza technika do generowania wartości hash (wykonawcze Hashable) w Swift? Czy powinienem używać XOR? Chociaż rozumiem, że XOR nie jest idealny do tworzenia jednolitych dystrybucji hash. Może coś bardziej egzotycznego?

+3

mógłby po prostu użyć operatory przepełnienia (& + i & *) umożliwiające przepełnienie liczb całkowitych w obliczeniach haszowania. https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/AdvancedOperators.html –

+0

Dobra uwaga. Muszę dokończyć czytanie książki Swift. ;) – orj

+1

Możesz chcieć edytować swoje pytanie. hashValue nie jest func. Zamiast tego jest to obliczona właściwość. – pohl

Odpowiedz

26

Jak sugeruje jeden Fabian Kreiser można używać operatorów przelewowym, aby metodę hashValue następująco:

var hashValue: Int { 
    return (31 &* property1.hashValue) &+ property2.hashValue 
} 

Wartość wciąż przelewa, ale przynajmniej nie psuje

+7

Możesz edytować odpowiedź. hashValue nie jest func. Zamiast tego jest to obliczona właściwość. – pohl

+0

ma to wpływ na to, który z nich wybiorę jako właściwość 1 lub właściwość 2? Załóżmy, że właściwość 1 przechodzi od 0 do 2, a właściwość 2 przechodzi od 0 do jakiegoś dużego ... – kfmfe04

+0

To podejście spowolniło mój czas kompilacji o współczynnik równy 10 000. Wersja Xcode 8.0 (8A218a). –