Swift에서 Equatable, Hashable, Comparable은 자주 사용하는 기본 프로토콜입니다. 이 프로토콜들은 객체 간의 비교 및 고유 식별이 필요할 때 활용되며 컬렉션 타입에서 객체의 정렬, 검색, 중복 확인 등을 쉽게 할 수 있게 합니다.
목차
3.
Equatable
Equatable 프로토콜은 두 객체의 동일성을 확인하기 위한 프로토콜입니다. Equatable을 준수하는 타입은 == 연산자를 통해 두 인스턴스가 같은지 비교할 수 있습니다. 주로 객체의 속성 값이 같은지 확인하여 동일성을 판단합니다.
특징
비교 연산 지원 | Equatable을 준수하는 타입은 자동으로 == 연산을 지원하며 != 연산도 함께 사용 가능 |
컬렉션에서 중복 확인 | Equatable 타입은 Set이나 Dictionary에서 중복을 확인할 수 있음 |
자동 구현 | Swift의 기본 자료형(Int, String, Array 등)은 Equatable을 준수하며 커스텀 타입도 모든 속성이 Equatable을 준수하면 자동으로 Equatable 프로토콜이 구현 |
장단점
장점 | 단점 |
객체의 동일성을 쉽게 비교 가능 | 모든 속성을 비교할 필요가 있는 경우 단점으로 작용할 수 있음 |
컬렉션에서 중복 확인 및 탐색이 용이 | 특정 속성만 비교하고 싶을 때는 커스텀 구현이 필요함 |
예제 코드
struct Person: Equatable {
var name: String
var age: Int
}
let person1 = Person(name: "범수", age: 25)
let person2 = Person(name: "범수", age: 25)
if person1 == person2 {
print("동일한 사람")
} else {
print("서로 다른 사람")
}
// 출력: 동일한 사람
Swift
복사
위 코드에서 Person 구조체는 Equatable을 준수하여 두 Person 객체의 name과 age가 모두 동일할 때 == 연산으로 비교 가능합니다.
Hashable
Hashable은 객체를 고유하게 식별하기 위해 해시 값을 제공하는 프로토콜입니다. 해시 값은 컬렉션에서 객체를 빠르게 찾기 위해 사용됩니다. Swift에서는 Hashable을 준수하면 Set 및 Dictionary의 키로 사용할 수 있습니다.
특징
고유 식별성 | 객체의 고유 식별을 위해 해시 값을 생성 |
효율적 검색 | Set과 Dictionary와 같은 자료구조에서 검색 속도를 최적화 |
자동 구현 | Equatable을 준수하는 모든 속성이 Hashable을 준수하면 Swift가 해시 값을 자동으로 생성 |
장단점
장점 | 단점 |
Set과 Dictionary에서 빠른 검색 가능 | 해시 충돌 발생 시 성능 저하 가능 |
객체의 고유성을 빠르게 확인 가능 | 모든 속성 값이 동일하면 해시 충돌 위험 있음 |
예제 코드
struct Product: Hashable {
var name: String
var price: Double
}
let product1 = Product(name: "iPhone", price: 999.99)
let product2 = Product(name: "MacBook", price: 1299.99)
var productSet: Set<Product> = [product1]
productSet.insert(product2)
print(productSet.contains(product1)) // 출력: true
Swift
복사
위 코드에서 Product 구조체는 Hashable을 준수하므로 Set에 삽입될 수 있으며 contains 메서드를 통해 빠르게 특정 객체가 포함되어 있는지 확인할 수 있습니다.
Comparable
Comparable은 객체 간의 순서를 비교하기 위한 프로토콜입니다. Comparable을 준수하는 타입은 <, <=, >, >= 연산자를 통해 순서를 비교할 수 있습니다. Swift에서 정렬 가능한 배열을 만들거나 특정 조건에 따라 객체를 나열할 때 사용됩니다.
특징
정렬 가능 | Comparable을 준수하는 타입은 sort()와 같은 정렬 메서드를 사용할 수 있음 |
순서 비교 지원 | 객체 간의 순서를 비교하여 컬렉션에서 유용하게 사용됨 |
자동 구현 불가 | 반드시 <= 연산자를 구현해야 함. 그러면 <, >, >=는 자동으로 구현 |
장단점
장점 | 단점 |
컬렉션에서 객체의 정렬이 가능 | 특정 순서 비교 기준이 필요할 때 직접 구현해야 함 |
값 비교를 통한 유연한 조건 처리 가능 | 복잡한 기준일 경우 구현이 다소 어려울 수 있음 |
예제 코드
struct Student: Comparable {
var name: String
var grade: Int
static func < (lhs: Student, rhs: Student) -> Bool {
return lhs.grade < rhs.grade
}
}
let student1 = Student(name: "범수", grade: 85)
let student2 = Student(name: "짱구", grade: 90)
let student3 = Student(name: "철수", grade: 80)
let students = [student1, student2, student3]
let sortedStudents = students.sorted()
for student in sortedStudents {
print("\(student.name): \(student.grade)")
}
// 출력:
// 철수: 80
// 범수: 85
// 짱구: 90
Swift
복사
위 코드에서 Student 구조체는 Comparable 프로토콜을 준수하여 grade를 기준으로 학생들을 정렬할 수 있습니다. sorted() 메서드를 호출하면 grade가 오름차순으로 정렬된 배열을 반환합니다.