ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Hashable in Swift 5
    Swift 2020. 6. 25. 19:48
    728x90

    요즘 CS193p 강의를 다시 보고 있는데 이런 내용이 있었나 와 정말 이렇게 알찬 강의였나 라는 생각이 계속 드네요
    너무도 배울게 많고 부족했던게 많았구나를 알려주는 강의인 것 같습니다.
    protocol 쪽을 보다가 Hashable에 대해 잠깐 짚어보고 넘어가려고 합니다 :)

     

    새로운 구조체나 클래스를 정의해서 객체를 만들었는데, 얘네들을 비교하고 싶다? 그럴 때 Hashable protocol 을 사용합니다.

    그럼 Hashable protocol은 뭘까요?

     


     

    Hashable protocol

     

    Hashable 을 뭐라고 설명하는지 먼저 살펴볼까요?

    integer hash value를 생성하는 Hasher로 hash 될 수 있는 타입.  

    한 마디로 Hashable protocol을 상속 받는다는 건 hash 될 수 있는 타입이라고 합니다.

    hash 가 될 수 있다는 건 뭘까요? 해시에 대한 기본적인 개념은 생략하고 해시 뜻만 보면, 위키백과에서는 이렇게 정의하고 있습니다.

    해시 함수에 의해 얻어지는 값은 해시 값, 해시 코드, 해시 체크섬 또는 간단하게 해시라고 한다.

    이걸로 유추해보면 해시가 될 수 있다 라는 건 HashTable 에서 찾을 수 있다는 의미입니다. 
    HashTable 에서 hash 값을 찾으려면 key가 필요하고 그 key는 식별할 수 있도록 unique 해야합니다.

    여기까지 이해하셨다면 Hashable protocol이 실제로 어떻게 되어 있는지 살펴볼게요.

    protocol Hashable: Equatable {
      var hashValue: Int { get }
      func hash(into hasher: inout Hasher)
    }

    위에서 말씀드린 hash 값을 찾을 수 있는 key 값인 hashValue가 필요합니다. 그리고 한 가지 더!

    Equatable protocol

    Hashable은 Equatable protocol 을 상속받고 있습니다. Equatable protocol 도 봐야겠죠? 

    protocol Equatable {
      static func == (lhs: Self, rhs: Self) -> Bool
    }

    네 역시 매우 씸플하네요. hashValue는 고유값이여야 하기 때문에 고유값인지 식별해줄 수 있는 == 함수가 필요합니다.
    우리가 값을 비교할 때 사용하는 == 연산자 있죠? 이게 바로 이 프로토콜 안에 들어있는 녀석입니다. 일반적으로 사용하는 Int, String, Double 등등 Apple에서 제공하는 다양한 기본 연산자들은 Hashable 타입을 이미 상속받고 있기 때문에 자연스럽게 == 연산자를 사용할 수 있었던 것이죠.

    Hashable 구현

    요약하면 Hashable 로 만들어 주려면 두 가지가 필요합니다.

    1. Equatable 에 있는 == 함수를 구현
    2. HashValue를 만든다.

    급하신 분들을 위해 바로 구현 예시를 먼저 보여드릴게요.

    var identifier = ... // 식별할 수 있는 변수
    
    ...
    
    static func ==(lhs: Self, rhs: Self) -> Bool {
      return lhs.identifire == rhs.identifire
    }
    
    func hash(into hasher: inout Hasher) {
      hasher.combine(identifire)
    }

    == 함수는 구현한다 치고, hash(into) 함수가 좀 생소하네요.

    현재 Swift 5 기준으로는 hashValue를 직접 설정해주는 건 deprecated 되었고 
    Hashable protocol에 있었던 func hash(into hasher: inout Hasher) 를 사용하라고 합니다.

    func hash(into hasher: inout Hasher) {
        hasher.combine(identifier)
      }

     

    Hashable protocol의 정의에서 봤듯이 Hasher는 hashValue를 생성해주는 녀석이라고 했어요!
    Hasher는 combine 이라는 메소드를 가지고 있습니다.

    즉 이 메소드를 사용해식별할 수 있는 identifire 를 hasher에게 넘겨주면 됩니다.

     

    자 이렇게 Hashable을 사용해 내가 만든 객체도 식별할 수 있게 만들 수 있습니다. 앞서 설명드렸듯이 Dictionary의 key, Set 에서 값을 찾는 기본 기능이며 이미 많은 기본 구조체들에서 상속받고 있습니다. 어려운 개념은 아니지만 저 같은 초보 입장에서는 자연스럽게 받아들이던 부분들에 대해 다시 한번 생각할 수 있는 시간이었네요. 

    감사합니다!!

     

    'Swift' 카테고리의 다른 글

    Reduce  (0) 2020.08.04
    ~= 연산자 in Swift  (0) 2020.07.07
    associatedType  (2) 2020.03.18
    @discardableResult  (0) 2020.03.18
    ARC(Autometic Reference Counting)  (0) 2020.02.03

    댓글

Designed by Tistory.