常见的Swift协议及其用途

133 阅读2分钟

1. Equatable

‘Equatable’ 协议用于类型进行相等性比较,两个实例是否“相等”。
必须实现‘==’运算符。

struct Person: Equatable {
    var name: String
    var age: Int
}
let person1 = Person(name: "Xiaoming", age: 20)
let person2 = Person(name: "Xiaoming", age: 20)
if person1 == person2 {
    print("person1 和 person2 '相等'")       
}

 // 打印:person1 和 person2 '相等'

2. Comparable

‘Comparable’ 协议用于类型进行排序,即两个实例之间的大小比较。

  1. 必须实现 ‘<’ 运算符,才能进行判断。
  2. 不必提供 <=、>、>= 的实现,如下源码可见,Comparable 协议通过扩展提供了 <=、>、>= 运算符的默认实现。
  3. Comprable 是继承自 Equatable 的, 所以 struct 不一定必须实现 == 方法,但是 class 中,一定要实现 == 方法

源码:

// Comparable 是继承自 Equatable的:
public protocol Comparable : Equatable {

     static func < (lhs: Self, rhs: Self) -> Bool

   
     static func <= (lhs: Self, rhs: Self) -> Bool

    
     static func >= (lhs: Self, rhs: Self) -> Bool


     static func > (lhs: Self, rhs: Self) -> Bool
 }
// Comparable协议的扩展
extension Comparable {

     public static func ... (minimum: Self, maximum: Self) -> ClosedRange<Self>

     @inlinable public static func > (lhs: Self, rhs: Self) -> Bool

     @inlinable public static func <= (lhs: Self, rhs: Self) -> Bool

     @inlinable public static func >= (lhs: Self, rhs: Self) -> Bool

     public static func ..< (minimum: Self, maximum: Self) -> Range<Self>

     prefix public static func ..< (maximum: Self) -> PartialRangeUpTo<Self>

     prefix public static func ... (maximum: Self) -> PartialRangeThrough<Self>
 
     postfix public static func ... (minimum: Self) -> PartialRangeFrom<Self>
 }

示例:

struct Animal: Comparable {
   var name: String
   var weight: Int
   
   static func < (lhs: Animal, rhs: Animal) -> Bool {
       return lhs.weight < rhs.weight
   }
}

let dog1 = Animal(name: "大黄", weight: 10)
let dog2 = Animal(name: "小黄", weight: 5)

if dog1 > dog2 {
   print("\(dog1.name)体重\(dog1.weight)kg, \(dog2.name)体重\(dog2.weight)kg, \(dog1.name)\(dog2.name)重") 
}

// 打印:大黄体重10kg, 小黄体重5kg, 大黄比小黄重

3. Codable

Codable 协议是 Encodable 和 Decodable 协议的组合,用于将 类型 -> 数据格式(如JSON) 或 从 数据格式 -> 类型 实例。
Swift 会自动为简单的结构体或类 生成 Codable 实现。

struct Person: Codable {
    var name: String
    var age: Int
}

let person = Person(name: "Xiaoming", age: 20)
if let jsonData = try? JSONEncoder().encode(person) {
    if let jsonString = String(data: jsonData, encoding: .utf8) {
        print(jsonString)    
        // 打印: {"age":20,"name":"Xiaoming"}
    }
}

4. Hashable

Hashable 协议用于类型在集合中(如Set或字典的键)使用;需要实现一个 hash(into:)方法,该方法计算实例的哈希值。
Swift对大多数简单类型提供了自动的 Hashable 实现。

struct Person: Hashable {
    var name: String
    var age: Int
}

let person1 = Person(name: "小明", age: 18)
let person2 = Person(name: "小红", age: 20)
let setOfPeople: Set = [person1, person2]
print(setOfPeople)

5. CustomStringConvertible

CustomStringConvertible 协议用于类型 自定义 description 属性,这个属性会返回一个 String 表示实例的描述,默认用于 print() 和字符串插值中

必须实现 description 属性。

struct Person: CustomStringConvertible {
    var name: String
    var age: Int
    
    var description: String {
        return "\(name), age \(age)"
    }
}

let person = Person(name: "John", age: 20)
print(person)     // John, age 20

6. Identifiable

Identifiable 协议通常用于定义唯一表示类型的 id 属性。
属性:必须实现 id 属性,该属性通常是唯一的标识符(如UUID)。

struct Person: Identifiable {
    var id = UUID()
    var name: String
    var age: Int
}

let person = Person(name: "John", age: 20)
print(person.id)   // 输出:一个唯一的UUID