2017-03-12 16 views
1

가정하자 나는 기본 클래스 I는 설정 (목록)에 추가 할 "사람"과 따라서 해쉬와 Equatable을 준수 할 필요가 있습니다에 "해쉬"프로토콜

class Person : Equatable, Hashable { 
let firstName: String 
let lastName: String 
var nickname: String? 
let dateOfBirth: NSDate 
var hashValue: Int { 
    if let nickname = nickname { 
     return firstName.hashValue^
       lastName.hashValue^
       nickname.hashValue^
       dateOfBirth.hashValue 
    } else { 
     return firstName.hashValue^
       lastName.hashValue^
       dateOfBirth.hashValue 
    } 

} 

init (firstName: String, lastName: String, nickname: String, bornOn dateOfBirth: NSDate) { 
    self.firstName = firstName 
    self.lastName = lastName 
    self.nickname = nickname 
    self.dateOfBirth = dateOfBirth 
    } 
} 

func ==(lhs: Person, rhs: Person) -> Bool { 
    return 
     lhs.firstName == rhs.firstName && 
     lhs.lastName == rhs.lastName  && 
     lhs.nickname == rhs.nickname  && 
     lhs.dateOfBirth == rhs.dateOfBirth 
} 

이 클래스는 옵션 속성이 하나뿐이므로 hashvalue를 만드는 데있어 선택적 요소를 다루는 것이 상당히 합리적입니다. 2 개 이상의 선택적 속성이 있다면 어떻게 될까요? 나는 이것이 아주 빨리 손에서 벗어나는 것을 볼 수있다.

선택적 속성은 일반적으로 객체를 해시 가능한 프로토콜에 부합시킬 때 어떻게 처리됩니까?

답변

3

해시 값 계산에 모든 속성을 기반으로 할 필요는 없습니다. 실제로, 그것은 어떤 것을 기반으로 할 필요가 없습니다. 당신은 단순히 하드 코딩 된 번호를 반환 할 수는 있지만 그렇게해서는 안됩니다.

하나 이상의 비 선택적 속성의 해시 값을 반환하면됩니다.

유일한 규칙은 동일한 것으로 비교되는 두 개체가 동일한 해시 값을 반환해야한다는 것입니다. 그러나 동일한 해시 값을 가진 두 객체가 동등한 것으로 훨씬 더 비교되어야한다는 요구 사항은 없습니다.

+0

소리가 적당합니다. 아마도 독자적인 토론을위한 주제 일지 모르지만, 향후 문제를 일으킬 수있는 hashValue 계산의 구체성을 줄이는 데 어떤 단점이 있습니까? – BrandonLenz

+1

해시 값이 좋지 않으면 개체를 컬렉션에 저장할 때 성능 문제가 발생할 수 있습니다. – rmaddy

+2

'hashValue'는'=='이'=='일 때 비효율적 일 때 최적화 할 수 있습니다. 해시가 동일하지 않으면 분명히 다른 값을 버릴 수 있습니다. 'hashValue'는 계산을 위해 O (1)이어야합니다. –

0

클래스가 배열의 요소로 사용할 Hashable 또는 Equatable 프로토콜을 준수 할 필요가 없다는 것을 추가하고 싶습니다. (이것은 내가 List를 의미한다고 가정 한 것입니다). 클래스를 Set의 요소 또는 Dictionary의 키로 사용하려면 Hashable 및 Equatable에 순응해야합니다. API reference of Hashable에 지정된대로 :

당신은 세트 또는 사전 키로 해쉬 프로토콜을 준수 모든 유형을 사용할 수 있습니다.

+1

예를 들어'index (of :)'또는'contains' 메소드를 사용하여 배열에서 객체를 검색하려면 Equatable을 준수해야합니다. – rmaddy

+0

네, 편의상'index (of :)'와'contains'에 클로저를 전달하고 엘리먼트 자체 만 전달하는 것을 피하기 원한다면. –