Equatable, Comparable, Hashable은 무엇인가?

Zeto·2022년 3월 30일
0

Swift_Study

목록 보기
10/18
post-custom-banner

swift에서는 다양한 라이브러리를 제공하는데 그 중에서도 대표적이라고 할 수 있는 프로토콜인 Equatable, Comparable, Hashable을 알아보고자 한다.

1) Equatable

Equatable 프로토콜은 그 이름과 같이 동일성을 비교하기 위한 프로토콜이다. 이를 채택할 경우 ==, != 연산을 사용할 수 있으며, 이와 함께 Sequence를 비롯한 Contains 등의 비교 연산을 사용하는 기능을 사용할 수 있다.

해당 프로토콜을 채택하면 필수적으로 == 연산을 구현해야 하고, 이외의 나머지 연산들은 == 연산을 기반으로 기본적인 구현체를 제공해준다. 이와 관련해서 약간의 조건도 존재한다.

  • 구조체(Struct) 타입일 경우에는 모든 저장 프로퍼티는 Equatable을 채택해야 한다. (Swift에서 제공하는 기본 타입들은 대부분 해당 조건을 충족.)
  • 열거형(Enum) 타입의 경우, 관련 연관 값들이 모두 Equatable을 채택해야 하며, 연관 값이 없을 경우에는 해당 프로토콜을 명시적으로 채택하지 않아도 자동으로 컴파일러가 채택을 해준다.

2) Comparable
Comparable 타입은 가진 값에 순서가 필요할 경우에 사용할 수 있는 프로토콜로서, 이를 채택할 경우 부등호(> / >= / < / <=)로 비교 연산이 가능해진다.
다만 해당 프로토콜은 Equatable을 상속받으므로 == 연산 구현과 함께 < 연산을 필수적으로 구현해줘야 한다. 이러한 필수 구현 요소만 작성하게 되면 나머지 부등호 연산들은 이들을 이용해서 구현할 수 있어서 기본 구현체를 제공하게 된다.

3) Hashable
Hasher를 통해 Int 타입의 hash 값을 만들어낼 수 있는 프로토콜로서 이를 적용한 타입은 Set이나 Dictionary에서 키로 사용할 수 있게 된다. 다만 해당 프로토콜을 채택하기 위해서는 상속한 Equatable 프로토콜도 구현해야하고, 이와 함께 hash()라는 함수를 필수적으로 구현해야 한다. 해당 함수는 Hasher를 인자 값으로 받고 이를 combine() 메서드를 통해 값을 제공하도록 구현된다.

Hashable은 왜 Equatable을 상속해야 하는가?

그렇다면 여기서 Hashable이 왜 Equatable을 상속하는지에 대한 의문이 들 수 있다. 이에 대한 이유를 들자면 hashValue라는 것은 고유값이 되어야 하기 때문에 고유값인지 아닌지에 대해 식별할 수 있는 ==라는 연산이 필요하기 때문이다.
다만 해당 연산을 구현하는 것은 Equatable이라는 프로토콜의 영역이기 때문에 Hashable은 필수적으로 해당 프로토콜을 상속할 수 밖에 없다.

그럼 Hash는 뭔데?

Hash라는 녀석은 Key를 고정된 크기의 Value로 저장하고, 이를 통해 값을 저장할 수 있다. 이러한 전체적인 과정을 뜯어볼 때, 원래 데이터의 값은 Key, 매핑 후의 데이터 값은 Hash Value, 매핑 과정을 hashing이라고 부른다.

이를 활용한 것이 HashMap인데, Key와 Value로 구성된 Entry 객체를 저장하는 구조를 가진 자료구조로서 Dicitonary와 비슷한 형태를 띈다. 당연히 Key는 중복 저장이 불가하고 기존 Key 값으로 신규 Value로 저장하면 기존 Value는 사라지고 신규 Value로 저장되게 된다.

profile
중2병도 iOS가 하고싶어
post-custom-banner

0개의 댓글