티스토리 뷰

Swift/Protocol

[Swift] Equatable Protocol이란?

ios상우 2023. 3. 29. 17:17

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
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
공지사항
링크
Total
Today
Yesterday