- 부족한 지식으로 공부하며 적어가고 있습니다. 틀린 부분이 있다면 댓글로 적어주시면 더 공부 후에 수정하겠습니다!
우리가 컨트롤 해야하는 것은 마인트 컨트롤만 있는건 아니다.
이번엔 Swift의 Set 컨트롤을 해보자.
struct TestStruct {
let n: Int
var str: String
}
TestStruct
를 Element로 갖는 Set을 가지려면 어떻게 해야할까?
-> 먼저 Hashable을 채택해야한다.
잠깐 여기가 시작이자 끝이다. 왜 Hashable을 채택해야하며 Hashable이 어떤 역할을 하는지 알아보자.
Hasable은 hash라는 함수를 통해 hasher라는 고유의 값을 만들어 낸다.
이 hasher의 고유한 값이 그 값이 Set에 빠르게 접근할 수 있는 키워드가 된다.
func hash(into hasher: inout Hasher) {
haser.combine(/*변수*/)
}
위 함수를 넣어주면 사용자가 직접 hasher에 어떤 변수를 어떤 순서로 만들지 결정할 수 있다.
하지만 서로 다른 값을 갖고 있는 TestStruct1
과 TestStruct6
이 hash 함수를 이용하면 같은
hasher를 갖을 수 있다. 우린 이걸 Hash 충돌이라고 한다.
[* Hash 충돌 해결에 대해서는 나중에 정리하자.]
Hash 충돌이 일어나면 Set는 충돌된 두 값이 같은 값인지 다른 값인지 판단해야한다.
그렇기에 Hashable은 Equatable을 채택하고 있다.
같은 값이면 같다고, 다르면 다르다고 알려줘야하기에
static func == (lhs: TestStruct, rhs: TestStruct) -> Bool {
/* 코드 기입 */
}
함수를 기입하면 된다.
실전
struct TestStruct {
let n: Int
var str: String
}
만약 TestStruct
에서 숫자 n 만 같으면 똑같은 값이야! 라고 설정하고 싶다.
그럼 우선 hasher가 n에 대해서만 관련 짓도록 만들어 Hash 충돌을 만들어야 한다.
struct TestStruct: Hashable {
let n: Int
var str: String
func hash(into hasher: inout Hasher) {
hasher.combine(n)
}
}
이렇게 n만 hasher에 combine 이뤄지면 hasher가 같기에 충돌이 일어날 것이다.
그럼 충돌 이후 두 값이 같음을 보여야 한다.
struct TestStruct: Hashable {
let n: Int
var str: String
func hash(into hasher: inout Hasher) {
hasher.combine(n)
}
static func == (lhs: TestStruct, rhs: TestStruct) -> Bool {
return lhs.n == rhs.n
}
}
==
함수를 적어 hasher가 n만 비교하는 것을 보여준다.
let testStruct1 = TestStruct(n: 3, str: "AAA")
let testStrcut2 = TestStruct(n: 3, str: "BBB")
var set = Set<TestStruct>([testStruct1, testStrcut2])
print(set) // [SwiftTest.TestStruct(n: 3, str: "AAA")]
testStruct1과 testStruct2가 Set에서는 같디고 판단되어 1개의 값만 저장 됨을 알 수 있다.