티스토리 뷰
Equatable은 기본 자료형들이 기본적으로 채택하고 있기도하고 개발문서를 보면 자주 볼 수 있는 프로토콜이더라구요!!
이것도 확실히 공부하고 넘어가려고 합니다!! 자 개발문서를 들어가 봅시다~!
A type that can be compared for value equality
값이 같은지 비교할 수 있는 타입입니다.
라고 해석해 봤는데 맞을까요!?
개요를 보고 좀 더 파악해봅시다~!
Equatable프로토콜을 채택한 타입(자료형)은
== 오퍼레이터를 사용해서 같은 값인지
!= 오퍼레이터를 사용해서 같은 값이 아닌지
비교할 수 있다고 합니다!
그리고 Swift 표준 라이브러리의 대부분의 기본 자료형은 Equatable을 채택하고 있다고 합니다
우리가 사용하던 그 비교 연산자들이 그냥 쓸 수 있는게 아니였네요
"A" == "B" // true
1 == 2 // false
2 == 2 // true
우리가 Swift로 코딩하면서 이렇게 ==이나 != 연산자를 이용해 비교할 수 있는 이유는 기본 자료형들이 Equatable을 채택하고 있기 때문었어요.
몇명 sequnce와 collection은 Equatable을 채택할 때 더 단순하게 작동될 수 있습니다.
예를 들어 배열이 특정 값이 포함되어 있는지 안되어 있는지 체크하고 싶을때
배열의 요소가 Equatable을 채택하고 있다면 클로저를 통해 직접 값을 비교하는 대신 값을 contains(_:)메소드에 직접 전달하여 찾을 수 있습니다.
이건 그것 같아요! 예를 들어 배열에 특정 값이 포함되어 있는지 안되어있는지 체크하고싶을때
array.forEach {
if $0 == "특정 값" {
//이런 식으로 찾는 것 보다
}
}
이런 식으로 클로저 구문을 이용해 직접 비교하고 찾는 것보다 contains(_:)메소드에 찾고 싶은 값을 전달해 쉽게 찾을 수 있다! 란 말입니다!
그럼 이제 기본 자료형들이 Equatable을 채택하고 있기 때문에 ==와 != 연산자를 사용할 수 있는건 알겠습니다~!
근데 커스텀 타입에서 ==와 != 연산자를 사용하는 방법을 알아봅시다!
Test 클래스를 하나 만들어볼게요
class Test {
var num: Int
init(_ num: Int) {
self.num = num
}
}
if Test(1) == Test(2) {
...
}
위 코드처럼 우리가 만든 커스텀 타입을 == 오퍼레이터를 사용하면 오류가 납니다! Test는 Equatable 프로토콜을 따르지 않기 때문이죠
그럼 Equatable을 채택해봅시다.
class Test: Equatable {
var num: Int
init(_ num: Int) {
self.num = num
}
}
그럼 이런 에러 문구가 따라옵니당
Type 'Test' does not conform to protocol 'Equatable'
프로토콜 채택했으면 프로토콜을 따르라 이거죠!
무엇을 구현해야 하는지 보러 가볼까요

public protocol Equatable {
/// Returns a Boolean value indicating whether two values are equal.
///
/// Equality is the inverse of inequality. For any values `a` and `b`,
/// `a == b` implies that `a != b` is `false`.
///
/// - Parameters:
/// - lhs: A value to compare.
/// - rhs: Another value to compare.
static func == (lhs: Self, rhs: Self) -> Bool
}
== 이란 옵셔널이 아닌 필수로 구현해야 하는 메소드가 하나 존재하네요 구현해줍시다~!
static func == (lhs: Test, rhs: Test) -> Bool {
return lhs.num == rhs.num
}
num은 정수 기본자료형인 Int로 구현되어 있으므로 이미 Equatable을 따르고 있어서 ==로 비교하면 됩니다
프로퍼티가 num 1개가 아니라 여러개라면 전부 비교해주고 && 연산자로 묶어주면 되겠죠?
번외로 필수 구현이 아닌 몇 메소드 들도 보입니다!
public static func != (lhs: Self, rhs: Self) -> Bool
@inlinable public func === (lhs: AnyObject?, rhs: AnyObject?) -> Bool
@inlinable public func !== (lhs: AnyObject?, rhs: AnyObject?) -> Bool
필요에 따라 구현해서 쓰셔도 될 것 같습니당
@inlinable이란? 메서드 호출을 해당 메서드의 본문으로 대체하는 컴파일러 최적화 방법
무슨 말인지 아시겠죠??
@inlinable public func printHello() {
print("Hello")
}
printHello() -> print("Hello") 로 대체되나봐요!
오버헤드가 감소하는 장점이 있지만 body에 재귀 같은 반복이 있으면 더 비효율적이라고 합니다
body가 단순한 함수에만 적용해야 하나봅니다!
그런고로 ===이나 !==는 따로 구현 안해도 쓸 수 있는 함수 인 것 같습니당 아니면 피드백 주세요!!
저도 따로 찾아보고 수정하겠습니다!!
'Swift > Protocol' 카테고리의 다른 글
[Swift] Identifiable Protocol이란? (0) | 2023.03.29 |
---|