Swift枚举属性didSet能否判断新旧值?带关联值枚举比较方案
在Swift枚举的didSet中检查新旧值是否相同的解决方案
你遇到的问题核心在于Swift枚举默认没有自动实现相等性判断,尤其是当枚举包含带关联值的case时,必须让枚举遵守Equatable协议才能直接比较两个实例是否相等。下面是具体的解决步骤:
1. 让枚举遵守Equatable协议
因为你的枚举关联值是String(已经符合Equatable),编译器会自动为你生成Equatable的实现,不需要手动编写==方法:
enum ViewState: Equatable { case idle case loading case caseWithAssociatedValue(String) }
2. 直接使用相等运算符比较新旧值
现在不管是在setState方法里,还是在didSet属性观察器中,都可以直接用!=或==来判断新旧状态是否一致:
方案一:保持原有的setState方法逻辑
修改后的setState可以正常过滤重复状态:
class View { private var state: ViewState = .idle func setState(to state: ViewState) { guard state != self.state else { return } self.state = state // 这里可以添加状态变化后的处理逻辑 } }
方案二:使用didSet观察器处理
如果你更倾向于用属性观察器来处理状态变化,也可以这样写:
class View { private var state: ViewState = .idle { didSet { guard oldValue != state else { return } // 状态真正发生变化时执行的逻辑 } } func setState(to state: ViewState) { self.state = state } }
3. 处理关联值类型不遵守Equatable的情况
如果你的枚举关联值是自定义类型且没有遵守Equatable,就需要手动实现Equatable的==方法来定义相等规则。举个例子:
// 自定义类型,未默认遵守Equatable struct CustomData { let id: Int let content: String } enum ViewState: Equatable { case idle case loading case caseWithAssociatedValue(CustomData) // 手动实现相等性判断 static func == (lhs: ViewState, rhs: ViewState) -> Bool { switch (lhs, rhs) { case (.idle, .idle), (.loading, .loading): return true case (.caseWithAssociatedValue(let lhsData), .caseWithAssociatedValue(let rhsData)): // 根据业务需求定义相等规则,比如比较id return lhsData.id == rhsData.id default: return false } } }
这样就能根据你自己的业务逻辑来判断带关联值的case是否相等了。
内容的提问来源于stack exchange,提问作者mike
相关产品推荐
相关产品推荐

