-
안녕하세요.
오늘은 Hashable Protocol에 대해서 알아보도록 하겠습니다.
https://developer.apple.com/documentation/swift/hashable/
와.. 한 문장에 hash라는 단어가 3번이나 쓰였습니다.
hash가 무엇인지 알고 가야하겠네요.
https://ko.wikipedia.org/wiki/해시_함수
해시 함수(hash function) 또는 해시 알고리즘(hash algorithm) 또는 해시함수알고리즘(hash函數algorithm)은 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑하는 함수이다. 해시 함수에 의해 얻어지는 값은 해시 값, 해시 코드, 해시 체크섬 또는 간단하게 해시라고 한다.
그니깐 결국 해시는 길이가 다른 데이터들이 해시함수를 거치면서 같은 길이의 데이터로 매핑된 값이네요.
Swift에서 대표적으로 Hash를 사용하는 자료구조는 Dictionary입니다.
직접 살펴보도록 하겠습니다.
이런 식으로 Dictionary 타입을 많이 사용하실 텐데요.
저도 Dictionary에서 값을 찾을 때 O(1)이라는 사실을 알고 있어 자주 애용합니다.
어떻게 Dictionary는 빠르게 값을 찾을 수 있는 걸까요?
Dictionary는 [Key: Value] 형태로 구성되어 있습니다.
제가 작성한 코드에서는 Key가 String 타입이고 Value가 Int 타입입니다.
중요한 것은 이 Key가 Hashable 해야 합니다.
만약
이런 식으로 직접 만든 타입을 Key값으로 사용한다면 Hashable하지 않다면서 에러를 발생시킵니다.
Dictionary가 값을 찾아오는 방법은 아래와 같습니다.
Hashable한 타입이 Hasher를 거치면 정수 타입의 해시 값을 생성하고 이 값을 인덱스처럼 사용해 바로 값을 가져옵니다.
그럼 Hasher가 무엇이냐
네. 해쉬 함수를 가지고 있는 구조체입니다.
Hashable한 타입들은 모두 이 Hasher를 이용해서 해시 값을 만들어 냅니다.
그렇다면 Custom Type들은 Hashable하게 만들 수는 없을까요?
전혀 그렇지 않습니다.
Hashable은 프로토콜이니깐 Custom Type들도 채택해주면 됩니다.
바로 이렇게 말이죠.
하지만 사실 이건 똑똑한 Swift가 Number의 프로퍼티가 모두 Hashable하단 것을 알아서 문제가 생기지 않은 겁니다.
이와 같이 Hashable하지 않은 프로퍼티를 가지고 있다면 Hashable을 준수하지 않는다고 합니다.
저 에러를 자세히 보면
Equatable 프로토콜을 준수하지 않았다고 뜨네요?
그렇습니다.
Hashable은 Equatable을 채택하고 있습니다.
그 이유는 해시 값은 유일해야하기 때문입니다.
Dictionary에서 Key값이 같은 값이 있으면 어떤 value를 찾는지 알 수 없습니다.
따라서 Key값이 유일한 값인지를 다른 값과 비교해야하기 때문에 Equatable을 채택하고 있습니다.
따라서 Equatable 프로토콜을 준수할 수 있게 == 연산자를 정의해주고
hash함수안에 hash값을 만드는데 사용할 값들(hashable 해야함)을 combine해주면 끝입니다.
위 코드에서는 alphabet과 hangul.munja를 key로 사용하기 위해서 두 값을 모두 combine하였습니다.
오늘은 여기까지 하겠습니다.
'Swift' 카테고리의 다른 글
Codable (0) 2021.12.28 NSCoder (0) 2021.12.27 escaping closure(탈출 클로저) (0) 2021.12.23 String은 왜 Int로 Subscript 되지 않을까? (0) 2021.12.15 class 와 struct 그리고 enum (4) 2021.12.14