Open Do-hyun-Kim opened 11 months ago
protocol
로 String
, Int
, Float
, Bool
, Set
에서 기본적으로 hash-value
를 제공하며, Custom Type에서도 hash
가 가능하다.Hashable
을 준수하는 모든 인스턴스는 hashValue
라는 정수형 프로퍼티를 갖고 있으며 이 값은 각각의 인스턴스를 식별하는 값이 된다.enum
에도 Hashable
채택하여 사용이 가능하다.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)
}
}
Equatable
이란 Type 끼리 비교 연산을 하기 위한 protocol
이며, 이를 준수 함으로써 등호 연산자(==)
, 다름 연산자(!=) 를 사용하여 비교할 수 있다. Equatable
protocol
을 준수하고 있다.Equatable
을 채택하여 비교 연산을 실행해야한다.class Jenny: Equatable {
var job: String
var name: String
init(job: String, name: String) {
self.job = job
self.name = name
}
static func == (lhs: Jenny, rhs: Jenny) -> Bool {
return lhs.name == rhs.name && lhs.job == rhs.job
}
}
class Person: Equatable {
var jenny: Jenny?
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
func isCompare(human: Jenny) {
if self.jenny != human {
print("different")
} else {
print("same")
}
}
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.jenny == rhs.jenny && lhs.age == rhs.age && lhs.name == rhs.name
}
}
hashValue
로 변환 시킬때 같은 값의 인스턴스는 Hasher에 같은 값을 전달해야 하기 때문이다.Hash 함수에 의해 얻어진 주소값(인덱스)으로서, Hash Table(배열)에 저장된 값을 찾을 수 있는 정수 타입
Dictionary
, Set
자료형에서 키값에 사용되려면 Hashable
프로토콜을 채택한 자료형이어야 함Int
, String
등의 Swift 기본 자료형은 자동으로 Hashable
프로토콜을 채택하고 있음Hashable
프로토콜을 채택할 경우
hash(into hasher: inout Hasher)
Hashable 프로토콜 메서드가 컴파일러에 의해 자동 구현됨hash(into hasher: inout Hasher)
Hashable 프로토콜 메서드와 == (lhs: T, rhs: T)
Equatable 프로토콜 메서드를 둘다 구현해 주어야 함전혀 다른 키값들이어도 해시 함수를 통해 얻은 동일한 해시 값이 여러 개일 경우, 해시 테이블에 저장할 때 충돌(Collision)이 발생할 수 있다. 이를 방지하기 위해서 Swift에서는 두가지 방법으로 Collision을 해결한다.
위에서 Hash Collision을 해결하기 위한 Linear Probing 기법이나 Separate Chaining 기법의 경우 중복되는 해시 값일 경우 해당 해시 값으로 만들어진 key 값의 유일성을 확인해야 한다. 그래야만 유일할 경우는 해당 해시 테이블 slot의 위치에 데이터을 덮어씌우고, 유일하지 않은 경우 Linear Probing 혹은 Separate Chaining 기법을 사용해서 데이터를 저장할 수 있다. 유일성을 확인하기 위해서 Key로 사용된 자료형의 데이터를 비교를한다.
예시)
class Person: Hashable {
var identifier: String {
return UUID().uuidString
}
var name: String
...
// Key로 사용된 Person 객채들의 해시값이 동일할 경우, 아래 프로퍼티를 비교함으로서 유일성을 확인한다
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.identifier == rhs.identifier
}
func hash(into hasher: inout Hasher) {
hasher.combine(identifier)
}
}
Key 라는 것을 Hash function를 이용하여 Hash 주소값(Hash Table의 index)으로 바꾸고, Hash 주소 값(Hash Table의 index)를 통해 Hash Table에 접근하여 값을 가져오거나 저장하는 형태
Hashable 해야 한다는 것 : Set에 저장하고 싶은 임의의 값의 타입은 Hashable 해야함 -> Hashable Protocol을 준수함
public protocol Hashable : Equatable {
var hashValue: Int { get }
func hash(into hasher: inout Hasher)
}
public protocol Equatable {
static func == (lhs: Self, rhs: Self) -> Bool
}
Hashable이란?
프로토콜 생김새
Equatable이란?
프로토콜 생김새
Hashable이 Equatable을 상속하는 이유
참고