Skip to main content

Command Palette

Search for a command to run...

[Swift] Set 컨트롤하기

Hashable과 Equatable을 채택하는 이유

Published
•View as Markdown
[Swift] Set 컨트롤하기
T

안녕하세요🙇🏻‍♂️ 세상을 더 편리하게 바꾸고 싶은 iOS 개발자 최인호입니다.

Hello 👋 I'm Inho Choi, an iOS developer who wants to change the world more conveniently.

  • 대학교 졸업
  • Apple Developer Academy @ POSTECH 1기
  • KWDC Main Organizer
  • AsyncSwift Organizer
  • 부족한 지식으로 공부하며 적어가고 있습니다. 틀린 부분이 있다면 댓글로 적어주시면 더 공부 후에 수정하겠습니다!

우리가 컨트롤 해야하는 것은 마인트 컨트롤만 있는건 아니다.

이번엔 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개의 값만 저장 됨을 알 수 있다.

More from this blog

[CS] Https는 대칭키일까? 비대칭키일까?

결론: 둘 다 쓴다. 하지만 쓰는 타이밍은 다르다. 자세하기 알아보자. 혹시 모르니 용어는 정리해두자. 암호화 <-> 복호화 해독 = 복호화 비대칭키 해독은 대칭키 해독보다 오래 걸린다. 비대칭키를 쓰는 과정 💡 비대칭키는 대칭키를 만들기 위한 여정에 쓰인다. 뭔 소리지??? 대칭키를 만들기 위해서 비대칭키가 쓰인다고?? 비대칭키 해독은 대칭키 해독보다 오래걸린다. 1. Client가 Server에 접속을 요청하면 서버는 Secret ...

Jun 6, 202417

Xcode Cloud 사용 후기

애플에게 내는 친구비를 내며 Apple Developer 계정을 유지하려면 매년 애플에게 13만원의 친구비를 지불해야한다. 그리고 몇 개 친구 답례 상품을 주는데 그 중 하나가 Xcode Cloud 상품 주는데 안 쓸 이유는 없지 Xcode Cloud 개인에게는 과연? K-Spam 이라는 앱을 오랫동안 구상하고 드디어 출시를 했다. 생각보다 삽질을 많이 한 것 같다. 하지만 사이드 프로젝트의 진정한 의미는 삽질(?)하며 배우는 것이 아니겠나 개...

Jun 3, 202418

iOS Version 주의

앱 버전에는 상위버전이 출시한 상태에서 하위 버전을 아카이브 할 수 없음 예를 들어 출시한 버전이 1.3 이면 1.2로는 아카이브가 불가능함 단, 출시한 적이 없는 앱이라면 버전은 마음대로 지정 가능 App Store Connect의 버전 예를 들어 1.03 이랑 1.1 이랑 비교하면 앱 버전은 1.03 > 1.1 로 인식한다. . 단위로 잘라서 Int로 인식하는 것 같다. 그러니 0은 최대한 사용하지 않고 구분한다면 . 으로 구분해야겠다.

Jun 1, 20248

Toby의 iOS 블로그

34 posts

안녕하세요 세상을 더 편리하게 바꾸고 싶은 iOS 개발자입니다.