Equatable
本课属于 Coddy Swift 学习旅程的“面向对象编程”单元。第 38 课,共 57 课。
Equatable 为类型提供 == 和 != 运算符。对于属性都符合 Equatable 的结构体和枚举,只需声明遵循该协议,Swift 就会比较每个属性:
struct Card: Equatable {
let rank: Int
let suit: String
}
let a = Card(rank: 10, suit: "hearts")
let b = Card(rank: 10, suit: "hearts")
print(a == b)
print(a != Card(rank: 2, suit: "hearts"))输出:
true
true如果只想比较某些属性,可以自己编写 static func ==。在这里,只要两个用户的 ID 相同,它们就相等,无论名字是什么:
struct User: Equatable {
let id: Int
var name: String
static func == (lhs: User, rhs: User) -> Bool {
lhs.id == rhs.id
}
}
print(User(id: 1, name: "Ada") == User(id: 1, name: "Ada L."))
print(User(id: 1, name: "Ada") == User(id: 2, name: "Ada"))输出:
true
falseEquatable可以启用需要比较的标准方法,例如在整个数组上使用 contains(_:)、firstIndex(of:) 和 ==:
struct Point: Equatable {
let x: Int, y: Int
}
let path = [Point(x: 0, y: 0), Point(x: 1, y: 2)]
print(path.contains(Point(x: 1, y: 2)))
print(path.firstIndex(of: Point(x: 1, y: 2))!)
print(path == [Point(x: 0, y: 0), Point(x: 1, y: 2)])输出:
true
1
true类不会自动获得 ==:它们使用 === 比较对象身份。需要按值比较的类必须自行实现 ==:
class Color: Equatable {
let hex: String
init(hex: String) { self.hex = hex }
static func == (lhs: Color, rhs: Color) -> Bool { lhs.hex == rhs.hex }
}挑战
简单Product 有 sku、name 和 price。当两个产品的 sku 相同时,它们就是同一个产品,其他字段的值不影响判断。让 Product 遵循 Equatable,并自定义 ==,然后完成 mergeCatalog(_:):它会保留每个产品第一次出现的记录(使用 contains),并返回由 sku name price 组成的行,最后跟上 removed: 2。
提供的代码会将产品读取为 sku,name,price 格式的行,并打印返回的每一行。
你的代码写在 Product.swift 和 Functions.swift 中。main.swift 包含提供的输入/输出代码,不能编辑。
亲手试试
// 提供的输入输出代码:保持原样。
var input: [String] = []
while let line = readLine() { input.append(line) }
let products = input.map { line -> Product in
let p = line.split(separator: ",").map(String.init)
return Product(sku: p[0], name: p[1], price: Int(p[2])!)
}
for line in mergeCatalog(products) { print(line) }
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Swift 在线编辑器