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。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。