Hashable
protocol
해시로 사용할 수 있는 타입.
Hasher로 integer hash 값을 생성한다.
Declaration
protocol Hashable
Overview
Hashable protocol을 준수한다면 Set 혹은 Dictionary key로 모든 타입을 사용할 수 있다.
String, integer, floating-point, boolean은 기본적으로 Hashable protocol을 준수하고 있다.
커스텀 타입도 해시 가능하다.
연관된 값 없이 enum을 정의하면, 자동적으로 Hashable을 준수한다.
그리고 커스텀 타입에다가 직접 hash(into:)를 구현하여 Hashable를 따르게 할 수 있다.
Conforming to the Hashable Protocol
Hashable protocol은 Equatable protocol을 상속받는다.
커스텀 Hashable 타입을 만들려면 아래의 조건들을 만족해야한다.
- 구조체: 저장 property들은 Hashable을 준수해야한다.
- enum : 관련된 값들은 모두 Hashable을 준수해야한다. (An enum without associated values has Hashable conformance even without the declaration.)
만약 위 조건들을 만족하지 못하거나, Hashable을 준수하게 확장하고 싶으면 hash(into:) 메소드를 구현해야한다.
struct GridPoint {
var x: Int
var y: Int
}
extension GridPoint: Hashable {
static func == (lhs: GridPoint, rhs: GridPoint) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
func hash(into hasher: inout Hasher) {
hasher.combine(x)
hasher.combine(y)
}
- hash(into:) 구현부에서 필수 구성요소들로 Hasher의 combine(_:)을 호출해야한다.
- Hashable, Equatable protocol의 요구사항을 만족하는지 확실하게 하기 위해, Equatable conformance(적합성)을 커스텀화 하면 좋다. (== 함수)
var tappedPoints: Set = [GridPoint(x: 2, y: 3), GridPoint(x: 4, y: 1)]
let nextTap = GridPoint(x: 0, y: 1)
if tappedPoints.contains(nextTap) {
print("Already tapped at (\(nextTap.x), \(nextTap.y)).")
} else {
tappedPoints.insert(nextTap)
print("New tap detected at (\(nextTap.x), \(nextTap.y)).")
}
// Prints "New tap detected at (0, 1).")
Topic
Providing a Hash Value
- func hash(into: inout Hasher)
- 이 값의 필수 구성요소를 제공된 Hasher를 통해 해시함.
hasher의 finalize()를 절대로 호출해서는 안됨.complie-time error 발생할 수 있음.
Leave a comment