例如說常在SwiftUI List, ForEach裡面用到的Identifiable

每次要做比較的時候都要寫一次Equatable的等價關係

如果善用protocol extenion的話,就可以針對大部分的Identifiable做一個通用的擴充

所有實作了Identifiable的對象都可以直接擴充Equatable,而不用再寫同樣的程式碼

注意:這邊只是因為個人開發習慣,所以相同 id 的物件會直接視為相同, 如果開發需要不同的比對方式,請自行修改。切勿照抄。

舉個例子,如果目前有一個Student,需要進行比對

classs Student: Equatable, Identifiable {
    let id = UUID()
    let name: String
}

一般寫完這段程式碼以後,要自己實作Equatable

extension Student {
    static func == (lhs: Student, rhs: Student) -> Bool {
      lhs.id == rhs.id
  }
}

如此,才能使用==來比對兩個物件是否相等。

不過,

如果沒有其他情況要特別比對,每次都只是比對id是否相等,那會產生大量的無用程式碼

所以這邊就可以用Protocol Extension來簡化程式碼。

extension Equatable where Self: Identifiable {
  static func == (lhs: Self, rhs: Self) -> Bool {
      lhs.id == rhs.id
  }
}

這樣就可以針對所有實作EquatableIdentifiable的物件進行一個預設的擴充。

如果有不一樣的需求,再自己實作一次介面方法就可以了。

import UIKit

class Student: Equatable, Identifiable {
    init(name: String) {
        self.name = name
    }

    let id = UUID()
    let name: String
}

let obj1: Student = .init(name: "1")
let obj2: Student = .init(name: "1")

extension Equatable where Self: Identifiable {
    static func == (lhs: Self, rhs: Self) -> Bool {
        lhs.id == rhs.id
    }
}

print(obj1 == obj2) // return false

//extension Student {
//    static func == (lhs: Student, rhs: Student) -> Bool {
//        lhs.name == rhs.name
//    }
//}
//
//print(obj1 == obj2) // return true