Equatable
聲明
protocol Equatable
概述
可以使用等於運算符 (==) 比較符合 Equatable 協議的類型,或者使用 not-equal-to 運算符 (!=) 比較不等式。 Swift 標準庫中的大多數基本類型都符合 Equatable 。
當元素符合 Equatable 時,可以更簡單地使用一些序列和集合操作。例如,要檢查數組是否包含特定值,您可以在數組元素符合 Equatable 時將值本身傳遞給 contains(_:) 方法,而不是提供確定等價的閉包。以下示例顯示了如何將 contains(_:) 方法用於字符串數組。
let students = ["Kofi", "Abena", "Efua", "Kweku", "Akosua"]
let nameToCheck = "Kofi"
if students.contains(nameToCheck) {
print("\(nameToCheck) is signed up!")
} else {
print("No record of \(nameToCheck).")
}
// Prints "Kofi is signed up!"
符合平等協議
將Equatable 一致性添加到您的自定義類型意味著您可以在搜索集合中的特定實例時使用更方便的 API。 Equatable 也是 Hashable 和 Comparable 協議的基本協議,允許更多地使用您的自定義類型,例如構造集合或對集合的元素進行排序。
當您在類型的原始聲明中聲明 Equatable 一致性並且您的類型滿足以下條件時,您可以依賴於自定義類型的 Equatable 協議要求的自動綜合:
-
對於
struct,其所有存儲的屬性必須符合Equatable。 -
對於
enum,其所有關聯值必須符合Equatable。 (即使沒有聲明,沒有關聯值的enum也具有Equatable一致性。)
要自定義類型的 Equatable 一致性,在不符合上述條件的類型中采用 Equatable,或擴展現有類型以符合 Equatable ,請實現等於運算符 ( == ) 作為您的類型的靜態方法。標準庫為任何 Equatable 類型提供了 not-equal-to 運算符 (!=) 的實現,它調用自定義 == 函數並否定其結果。
例如,考慮一個 StreetAddress 類,它包含街道地址的各個部分:房屋或建築物編號、街道名稱和可選的單元編號。這是 StreetAddress 類型的初始聲明:
class StreetAddress {
let number: String
let street: String
let unit: String?
init(_ number: String, _ street: String, unit: String? = nil) {
self.number = number
self.street = street
self.unit = unit
}
}
現在假設您有一個地址數組,需要檢查特定地址。要使用 contains(_:) 方法而不在每次調用中包含閉包,請擴展 StreetAddress 類型以符合 Equatable 。
extension StreetAddress: Equatable {
static func == (lhs: StreetAddress, rhs: StreetAddress) -> Bool {
return
lhs.number == rhs.number &&
lhs.street == rhs.street &&
lhs.unit == rhs.unit
}
}
StreetAddress 類型現在符合 Equatable 。您可以使用 == 檢查任何兩個實例之間的相等性或調用 Equatable -constrained contains(_:) 方法。
let addresses = [StreetAddress("1490", "Grove Street"),
StreetAddress("2119", "Maple Avenue"),
StreetAddress("1400", "16th Street")]
let home = StreetAddress("1400", "16th Street")
print(addresses[0] == home)
// Prints "false"
print(addresses.contains(home))
// Prints "true"
平等意味著可替代性——任何兩個比較相等的實例都可以在取決於它們的值的任何代碼中互換使用。為了保持可替代性,== 運算符應考慮 Equatable 類型的所有可見方麵。不鼓勵公開 Equatable 類型的非值方麵而不是類標識,並且任何 are 公開的內容都應在文檔中明確指出。
由於 Equatable 類型的實例之間的相等性是等價關係,因此任何符合 Equatable 的自定義類型都必須滿足三個條件,對於任何值 a 、 b 和 c :
-
a == a始終是true(自反性) -
a == b暗示b == a(對稱) -
a == b和b == c意味著a == c(傳遞性)
此外,不等式是等式的逆,因此 != 運算符的任何自定義實現都必須保證 a != b 意味著 !(a == b) 。 != 運算符函數的默認實現滿足此要求。
平等與身份是分開的
類實例的標識不是實例值的一部分。考慮一個名為IntegerRef 的類,它包含一個整數值。以下是 IntegerRef 的定義和使其符合 Equatable 的 == 函數:
class IntegerRef: Equatable {
let value: Int
init(_ value: Int) {
self.value = value
}
static func == (lhs: IntegerRef, rhs: IntegerRef) -> Bool {
return lhs.value == rhs.value
}
}
== 函數的實現返回相同的值,無論它的兩個參數是相同的實例還是兩個不同的實例,它們的value 屬性中存儲了相同的整數。例如:
let a = IntegerRef(100)
let b = IntegerRef(100)
print(a == a, a == b, separator: ", ")
// Prints "true, true"
另一方麵,類實例標識使用triple-equals identical-to 運算符(===)進行比較。例如:
let c = a
print(c === a, c === b, separator: ", ")
// Prints "true, false"
可用版本
相關用法
- Swift EnumeratedSequence forEach(_:)用法及代碼示例
- Swift EnumeratedSequence.Iterator map(_:)用法及代碼示例
- Swift EnumeratedSequence.Iterator flatMap(_:)用法及代碼示例
- Swift EmptyCollection first(where:)用法及代碼示例
- Swift ExpressibleByIntegerLiteral用法及代碼示例
- Swift EmptyCollection index(_:offsetBy:limitedBy:)用法及代碼示例
- Swift EnumeratedSequence drop(while:)用法及代碼示例
- Swift EmptyCollection partition(by:)用法及代碼示例
- Swift EnumeratedSequence.Iterator allSatisfy(_:)用法及代碼示例
- Swift ExpressibleByStringInterpolation init(stringInterpolation:)用法及代碼示例
- Swift EmptyCollection prefix(upTo:)用法及代碼示例
- Swift EmptyCollection starts(with:)用法及代碼示例
- Swift EnumeratedSequence用法及代碼示例
- Swift EmptyCollection.Iterator split(maxSplits:omittingEmptySubsequences:whereSeparator:)用法及代碼示例
- Swift EmptyCollection.Iterator starts(with:)用法及代碼示例
- Swift EnumeratedSequence.Iterator drop(while:)用法及代碼示例
- Swift EmptyCollection.Iterator prefix(_:)用法及代碼示例
- Swift EmptyCollection sorted(by:)用法及代碼示例
- Swift EmptyCollection dropFirst(_:)用法及代碼示例
- Swift EnumeratedSequence dropFirst(_:)用法及代碼示例
- Swift EnumeratedSequence.Iterator filter(_:)用法及代碼示例
- Swift EmptyCollection enumerated()用法及代碼示例
- Swift EmptyCollection sort()用法及代碼示例
- Swift EnumeratedSequence.Iterator reduce(into:_:)用法及代碼示例
- Swift EnumeratedSequence compactMap(_:)用法及代碼示例
注:本文由純淨天空篩選整理自apple.com大神的英文原創作品 Equatable。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。
