안녕하세요 :) 소들입니다
연말 정산 글에 1주일에 글 1개 안쓰면 게임 1주일 접겠다고
뭔 망언을 해놔서..; 게임을 접을 수 없어 글을 쓰는 이 지경입니다 제가
어떤 분이 메타 타입에 대해 글을 써달라 하셨는데,
내용이 너무 길어질 것 같아서 그건 다음으로 미루고
처음 접했을 때 어려울 수 있는 프로토콜 몇가지에 대해 정리부터 하려고 합니다!!
뭐 Equatable이나 Hashable이나 Comparable이나 등등!!!!
(절대 내용 짧을 거 같아서 그런거 절대 아닐 거임)
모든 포스팅은 편의 말투로 합니다~!
1. Int, String 끼리는 비교가 되면서 왜 구조체, 클래스 인스턴스끼리는 비교가 안 될까
위 말이 뭔말이셈이냐면,
우리가 다음과 같이 아무렇지 않게 사용해오던
let num1 = 3
let num2 = 3
num1 == num2 // true
let str1 = "so"
let str2 = "deul"
str1 == str2 // false
|
== 이 연산자가 바료 비교 연산자란 말임
근데 위처럼 num, str끼리는 == 연산자를 써서 위처럼 비교를 할 수 있고,
원하는 결과(true, false)도 얻을 수 있지만
struct Human {
var name = ""
var age = 0
}
let human1 = Human.init()
let human2 = Human.init()
human1 == human2 // Binary operator '==' cannot be applied to two 'Human' operands
|
우리가 만든 구조체, 클래스 인스턴스를 ==로 비교하려고 하면
위처럼 에러가 뜸
그 이유가 무엇이냐면,
Int, Double, String이란 자료형은 가장 기본적인 자료형으로,
Equatable이란 프로토콜이 이미 모두 채택되어 컴파일러가 자동으로 구현해주기 때문임
그래서 도대체 Equatable이 뭐냐고?
Equatable은 타입끼리 비교(==)연산을 하기 위해선 필수적으로 구현해야 하는 프로토콜!!
안에 static func == 이거 보이시져??
타입끼리 ==을 쓰기 위해서 필수적으로 채택해야 하는 게 Equatable이란 프로토콜이구나~!
채택하고 나서 func ==를 구현 해줘야 하는구나~!
정도로 알면 되겠다!!
그럼 이제 구조체, 클래스, 열거형에서 Equatable을 사용하는 방법에 대해 알아 보겠음 :)
2. 구조체 / 클래스/ 열거형에서 비교 연산을 쓰는 방법
2-1. 구조체
앞서 말했듯 같은 구조체 인스턴스끼리 비교를 하고 싶다면,
Equatable 프로토콜을 채택하면 됨
struct Human: Equatable {
var name = ""
var age = 0
}
let human1 = Human.init()
let human2 = Human.init(name: "", age: 19)
human1 == human2 // false
|
이렇게 Human 구조체에 Equatable 프로토콜을 채택해주면,
이젠 Human 인스턴스끼리 비교가 가능해짐!!
에엥 프로토콜 내에 정의되어 있는 ==이란 메서드에 대해 구현 안 해줬는데요?
라고 할 수 있지만,
열거형 내 모든 타입이 기본 타입(name: String, age: Int)라면,
직접 메서드를 구현해주지 않아도 Equatable을 채택하는 것만으로도 사용 가능함
참고로 이렇게 할 경우,
해당 구조체 내의 모든 프로퍼티(name, age)가 같아야만 true임
만약 나는 이름이 같으면 같은 인스턴스로 취급하고 싶어!! 라고 한다면,
struct Human: Equatable {
var name = ""
var age = 0
static func == (lhs: Self, rhs: Self) -> Bool {
return lhs.name == rhs.name
}
}
let human1 = Human.init()
let human2 = Human.init(name: "", age: 19)
human1 == human2 // true
|
이렇게 직접 구현해주면, name에 한해서만 비교를 하기 때문에
human1과 human2의 age란 프로퍼티가 달라도 둘은 동일하다고 비교하게 만들 수도 있음
(근데 웬만해서 특수하진 않은 경우, 걍 기본을 쓰는게..ㅎㅎ)
2-2. 클래스
흐헿ㅎ 구조체처럼 Equatable 채택만 하면 자동으로 되겠지 흫헿
class Human: Equatable { // Type 'Human' does not conform to protocol 'Equatable'>
var name = ""
var age = 0
}
|
응 어림도 없어
클래스의 경우 Equatable을 채택하는 것만으로 자동으로 구현해주지 않음
따라서 직접 == 메서드를 구현해야 함
class Human {
var name = ""
var age = 0
}
extension Human: Equatable {
static func == (lhs: Human, rhs: Human) -> Bool {
return lhs.name == rhs.name && lhs.age == rhs.age
}
}
let human1 = Human.init()
let human2 = Human.init()
human2.age = 10
human1 == human2 // false
|
그렇다고 합니다 :D
2-3. 열거형
1️⃣ 연관값이 없는 열거형
연관값이 없는 열거형의 경우,
enum Gender {
case male
}
let man = Gender.male
let man2 = Gender.male
man == man2 // true
|
Equatable을 채택하지도 않아도 자동으로 구현이 됨
2️⃣ 연관값이 있는 열거형
연관값이 있는 열거형의 경우,
enum Gender: Equatable {
case male(name: String)
}
let man = Gender.male(name: "so")
let man2 = Gender.male(name: "deul")
man == man2 // false
|
Equatable을 채택만 해줘도 자동으로 구현이 됨
(채택은 필수, ==메서드 구현은 필수 X)
.
.
.
오늘은 Equatable이란 프로토콜에 대해 알아봤어요!
어렵진 않지만 제대로 모를 땐 헷갈릴 수 있을 것 같아서
확실하게 정리하고 가시길 바라겠습니다 :)
오타 및 피드백 대환영
'iOS > Swift' 카테고리의 다른 글
Swift) Comparable에 대해 알아보자 (6) | 2022.01.30 |
---|---|
Swift) Hashable에 대해 알아보자 (11) | 2022.01.25 |
Swift5+) @unknown(Unfrozen Enumertaion) (10) | 2021.12.03 |
Swift) Dispatch를 이용한 성능 최적화 (9) | 2021.10.16 |
Swift) Static Dispatch & Dynamic Dispatch (2/2) (1) | 2021.10.13 |