개발을 하다보니 Swift에 기본적으로 구현되어있는 프로토콜에 대한 이해가 필요할거같아서 이참에 한번 정리해보기로 했다
원칙)
예외)
enum SuperComputer: Equatable {
case cpu(core: Int, ghz: Double)
case ram(Int)
case hardDisk(gb: Int)
}
SuperComputer.cpu(core: 8, ghz: 3.5) == SuperComputer.cpu(core: 16, ghz: 3.5)
SuperComputer.cpu(core: 8, ghz: 3.5) != SuperComputer.cpu(core: 8, ghz: 3.5)
enum Direction {
case east
case west
case south
case north
}
Direction.north == Direction.east // false
Direction.north != Direction.east // true
struct Dog {
var name: String
var age: Int
}
extension Dog: Equatable {}
let dog1: Dog = Dog(name: "초코", age: 10)
let dog2: Dog = Dog(name: "보리", age: 2)
dog1 == dog2
dog1 != dog2
class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
// 특별한 이유가 없다면 모든 속성에 대해, 비교 구현
extension Person: Equatable {
static func ==(lhs: Person, rhs: Person) -> Bool {
return lhs.name == rhs.name && lhs.age == rhs.age
//return lhs.name == rhs.name // 이름만 같아도 동일하다고 보려면 이렇게 구현
//return lhs.age == lhs.age // 나이만 같아도 동일하다고 보려면 이렇게 구현
}
}
let person1: Person = Person(name: "홍길동", age: 20)
let person2: Person = Person(name: "임꺽정", age: 20)
person1 == person2
person1 != person2
원칙)
예외)
enum Direction: Int {
case east
case west
case south
case north
}
extension Direction: Comparable {
static func < (lhs: Direction, rhs: Direction) -> Bool {
return lhs.rawValue < rhs.rawValue
}
}
Direction.north < Direction.east // false
Direction.north > Direction.east // true
enum SuperComputer: Hashable {
case cpu(core: Int, ghz: Double)
case ram(Int)
case hardDisk(gb: Int)
}
let superSet: Set = [SuperComputer.cpu(core: 8, ghz: 3.5),
SuperComputer.cpu(core: 16, ghz: 3.5)]
→SuperComputer의 경우 Set의 요소가 되기 위해서는 Hashable프로토콜 채택
struct Dog {
var name: String
var age: Int
}
extension Dog: Hashable {}
let dog1: Dog = Dog(name: "초코", age: 10)
let dog2: Dog = Dog(name: "보리", age: 2)
let dogSet: Set = [dog1, dog2]
→Dog의 경우 Set의 요소가 되기 위해서는 Hashable프로토콜 채택
class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
Person타입을 Set의 원소로 넣으려면 Hashable프로토콜을 채택해야하는데 채택만하면 구현을 해주는게 아닌, 실제로 전부다 구현해야한다
extension Person: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(name)
hasher.combine(age)
}
**Hashable프로토콜을 Equatable프로토콜을 상속받기때문에 필수구현**
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.name == rhs.name && lhs.age == rhs.age
}
}
let person1: Person = Person(name: "홍길동", age: 20)
let person2: Person = Person(name: "임꺽정", age: 20)
let personSet: Set = [person1, person2]
enum Color: CaseIterable {
case red, green, blue
}
→ 모든 케이스를 (정의한 순서대로) 포함한 배열을 리턴
Color.allCases // [Color.red, Color.green, Color.blue]
// 공식문서의 예제
enum CompassDirection: CaseIterable {
case north, south, east, west
}
print("방향은 \(CompassDirection.allCases.count)가지")
// 배열을 문자열화
let caseList = CompassDirection.allCases
.map({ "\($0)" })
.joined(separator: ", ")
// result : "north, south, east, west"
let randomValue = CompassDirection.allCases.randomElement()
enum RpsGame: Int, CaseIterable {
case rock = 0
case paper = 1
case scissors = 2
}
let number = Int.random(in: 0...100) % 3
// 나머지를 구하는 것이니 무조건 0, 1, 2 중에 한가지임
// 100대신 RpsGame.allCases.count를 넣어도됨
// 변수에 넣고 쓰면 더 깔끔한 코드로도 변형 가능
let number2 = Int.random(in: 0...100)%RpsGame.allCases.count