带关联值的枚举
发布
更新
字数
503
阅读
3 分钟
阅读量
896
带关联值的枚举,可以使其成员携带更多信息。参考官方文档:https://docs.swift.org/swift-book/documentation/the-swift-programming-language/enumerations/#Associated-Values
关联值的获取与比较
主要有两种方式。switch case
模式可以遍历全部成员并作出回应,如果只对一个或部分成员感兴趣,可以使用 if case
语句赋值比较。
enum Item {
case text(String)
}
let textA: Item = .text("a")
// 也可以写成
if case let .text(a) = textA {
print(a)
}
修改关联值
如果需要修改枚举值的关联值,我们可以为其增加一个 mutating
函数
extension Item {
mutating func append(_ aString: String) {
switch self {
case .text(let string):
self = .text(string.appending(aString))
}
}
}
Hashable
Hashable enumeration 在 diffable data source 中使用非常方便。上例中,枚举关联值类型为 String
是 hashable 的,所以只需要扩展一个协议即可
extension Item: Hashable {}
如果关联值不全是 Hashable
类型,需要手动实现相应的方法
enum ActionItem {
typealias Action = () -> Void
case text(String, action: Action)
}
extension ActionItem: Hashable {
static func == (lhs: ActionItem, rhs: ActionItem) -> Bool {
// 比较主要关联值
if case let .text(lString, _) = lhs, case let .text(rString, _) = rhs {
return lString == rString
}
return false
}
// `hash(into:)` 方法与 `==` 方法关注的值是一样的
func hash(into hasher: inout Hasher) {
switch self {
case let .text(string, _):
hasher.combine(string)
}
}
}
其他
我们还可以为 ActionItem
添加一个便利方法
extension ActionItem {
func excute() {
// 注意这里获取关联值时,把 `let` 放在了括号里面也是可以的,
// 与 `switch` 一样支持两种写法
if case .text(_, let action) = self {
action()
}
}
}
在上面比较两个枚举值是否相等时用到了 if case let .text(lString, _) = lhs, case let .text(rString, _) = rhs
获取关联值,我们也可以添加一个计算属性
extension ActionItem {
var associatedValue: String {
switch self {
case .text(let string):
return string
}
}
}
//...
// 然后
//...
static func == (lhs: ActionItem, rhs: ActionItem) -> Bool {
// 这里省略了 `return`
lhs.associatedValue == rhs.associatedValue
}