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

如何修改Swift枚举类中的只读items属性值?

解决枚举只读属性无法修改的问题

问题根源

你定义的ShopItemSelection枚举中,items是只读计算属性(仅包含get逻辑),因此无法直接赋值修改。要实现动态过滤.clothes的需求,以下是几种优雅的解决方案:


方案一:给枚举添加关联值,支持动态过滤标记

通过给枚举case添加默认关联值,控制是否过滤指定元素,既保留枚举的默认值特性,又能灵活调整返回的items:

import Foundation

enum ShopItemSelection: Hashable {
    // 给case添加默认关联值,默认不排除clothes
    case ralph(excludeClothes: Bool = false)
    case target(excludeClothes: Bool = false)

    var items: [ShopItem] {
        // 先获取对应case的基础items数组
        let baseItems: [ShopItem]
        switch self {
        case .ralph:
            baseItems = [.meat, .clothes, .fruit]
        case .target:
            baseItems = [.meat, .clothes, .fruit, .veggies]
        }
        
        // 根据关联值判断是否过滤.clothes
        switch self {
        case .ralph(let exclude), .target(let exclude):
            return exclude ? baseItems.filter { $0 != .clothes } : baseItems
        }
    }
}

使用时直接在初始化枚举时传入过滤标记:

var sections: [ShopItemSelection] = []
        
switch store.size {
case "SMALL":
    sections.append(.ralph(excludeClothes: !store.stillHaveClothes))
default:
    sections.append(.target(excludeClothes: !store.stillHaveClothes))
}
        
return sections

方案二:用结构体包装枚举,实现自定义items

如果不想修改原有枚举的定义,可以创建一个结构体来包装枚举类型和自定义items,通过结构体的可变属性实现动态修改:

// 保持原有枚举不变
enum ShopItemSelection: Hashable {
    case ralph
    case target

    var items: [ShopItem] {
        switch self {
        case .ralph:
            return [.meat, .clothes, .fruit]
        case .target:
            return [.meat, .clothes, .fruit, .veggies]
        }
    }
}

// 新增包装结构体
struct ShopSection {
    let type: ShopItemSelection
    var customItems: [ShopItem]?
    
    // 对外暴露统一的items访问入口
    var items: [ShopItem] {
        return customItems ?? type.items
    }
}

使用时通过修改结构体的customItems属性实现过滤:

var sections: [ShopSection] = []
        
switch store.size {
case "SMALL":
    sections.append(ShopSection(type: .ralph))
default:
    sections.append(ShopSection(type: .target))
}
        
if !store.stillHaveClothes {
    sections[0].customItems = sections[0].type.items.filter { $0 != .clothes }
}
        
return sections

方案三:给枚举添加存储属性(不推荐)

这种方式会让枚举带有可变状态,破坏枚举作为纯值类型的设计初衷,仅在特殊场景下使用:

enum ShopItemSelection: Hashable {
    case ralph
    case target
    
    // 存储过滤后的数组,默认nil时使用基础items
    private var filteredItems: [ShopItem]?
    
    var items: [ShopItem] {
        get {
            return filteredItems ?? baseItems
        }
        set {
            filteredItems = newValue
        }
    }
    
    // 提取基础items到私有计算属性
    private var baseItems: [ShopItem] {
        switch self {
        case .ralph:
            return [.meat, .clothes, .fruit]
        case .target:
            return [.meat, .clothes, .fruit, .veggies]
        }
    }
}

此时你原来的代码可以直接运行,因为items现在有了setter方法。

内容的提问来源于stack exchange,提问作者Seb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 12:55:19