You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:45:21