Dictionary<keyType, valueType>
struct GridPoint {
// 아직은 hash 불가능 -> Set / Dictionary Key로 사용 불가능
var x: Int
var y: Int
}
Set / Dictionary Key가 Hashable 해야하는 이유
- Hash 함수: 임의의 길이의 데이터를 고정된 길이의 데이터로 mapping하는 함수
x --> (Hash함수 통과) --> 해시값 / Hash- 이용:
- Hashable == HashTable에서 찾을 수 있다!
- 검색/탐색을 빨리하려고 Hashtable에서 사용.- Set과 Dictionary는 array와 달리 순서가 없으므로 Hashable과 관련이 있는 것임.
자동으로 hashable 해지는 경우
- struct: 저장 property가 모두 hashable할 경우
- enum: 모든 associated value가 hashable할 경우
- associated value가 없으므로 Hashable 준수가 자동으로 적용되어 바로 hashable
- 자동으로 적용되지만, 원한다면 hashValue property를 사용자가 직접 추가해서 사용자정의 타입에 Hashable 준수를 추가할 수 있음.
수동으로 hashable하게 바꾸는 방법
(조건에 부합하지 않지만, hashable하게 만들고 싶은 경우.)
- Hashable
== HashTable에서 찾을 수 있다!
== hashValue(unique한 key)가 필요하다!방법
1) 사용자정의 property에 hashValue property 구현
2) == 연산자 제공
(그러나, swift가 update되면서 자동으로도 가능)1. 자동
struct GridPoint: Hashable { // Hashable 붙여주면 알아서 hashable하게 바꿔줌 var x: Int var y: Int } . // Set에 사용 가능 var setEx = Set<GridPoint>() // Dictionary Key로 사용 가능 var dictEx: [GridPoint: Int] = [:]
2. 수동
protocol Hashable: Equatable { var hashValue: Int {get} func hash(into hasher: inout Hasher) }
protocol Equatable { static func == (lhs: Self, rhs: Self) -> Bool }
1) Equatable의 == 구현
- hashValue는 고유한 값이므로, 이를 == function을 통해 판단하는 것
static func == (lhs: Self, rhs: Self) -> Bool { return lhs.identifier == rhs.identifier }
2) hashValue(unique한 Key) 만들기
func hash (into hasher: inout Hasher) { hasher.combine(identifier) }
- hashValue를 직접 설정해줄 수 없어서
Hasher를 사용해서 hashValue를 설정해주는 것!- combine: indentifier를 hasher에 넘겨주는 역할
-func combine<H>(_ value: H) where H: Hashable