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

Swift中如何根据键返回匹配类型的存储值?

核心问题分析

当前实现的getStoredValue泛型参数T与StorageKeys没有绑定关系,编译器无法根据传入的键自动推断T的类型——调用时若不手动指定T,会直接触发编译错误,达不到“返回值类型与传入键自动匹配”的预期效果。

解决方案

方案1:为枚举添加专属取值方法(最直观,低复杂度)

直接给StorageKeys扩展对应每个case的专属方法,返回固定类型的可选值,彻底避免泛型模糊性:

enum StorageKeys: String {
    case PREFERENCES
    case SCORE
}

extension StorageKeys {
    func getPreferences() -> Preferences? {
        return Storage.shared.getObject(self.rawValue) as? Preferences
    }
    
    func getScore() -> Score? {
        return Storage.shared.getObject(self.rawValue) as? Score
    }
}

// 调用示例
let prefs = StorageKeys.PREFERENCES.getPreferences()
print(prefs?.language)

let score = StorageKeys.SCORE.getScore()
print(score?.points)

优点:代码清晰,调用时类型明确,无类型不匹配风险,维护成本极低。

方案2:枚举关联类型映射(泛型优化版)

若希望保留泛型灵活性,可给StorageKeys添加类型映射逻辑,让泛型函数能根据键推断返回类型:

enum StorageKeys: String {
    case PREFERENCES
    case SCORE
    
    private func targetType<T>() -> T.Type? {
        switch self {
        case .PREFERENCES:
            return Preferences.self as? T.Type
        case .SCORE:
            return Score.self as? T.Type
        }
    }
}

func getStoredValue<T>(forKey key: StorageKeys) -> T? {
    guard key.targetType<T>() != nil,
          let value = Storage.shared.getObject(key.rawValue) as? T else {
        return nil
    }
    return value
}

// 调用示例(通过变量类型推断或显式指定T)
let prefs: Preferences? = getStoredValue(forKey: .PREFERENCES)
print(prefs?.language)

优点:保留泛型写法,扩展性较好(新增键时仅需修改targetType方法);缺点:调用时仍需依赖类型推断或显式指定T,直观性略逊于方案1。

方案3:带关联值的枚举(强类型绑定)

将StorageKeys改为带关联值的枚举,直接把类型与键绑定,从根源消除类型不匹配可能:

enum StorageKey {
    case preferences(Preferences.Type)
    case score(Score.Type)
    
    var rawValue: String {
        switch self {
        case .preferences:
            return "PREFERENCES"
        case .score:
            return "SCORE"
        }
    }
}

func getStoredValue<T>(forKey key: StorageKey) -> T? {
    guard let value = Storage.shared.getObject(key.rawValue) as? T else {
        return nil
    }
    return value
}

// 调用示例
let prefs = getStoredValue(forKey: .preferences(Preferences.self))
print(prefs?.language)

优点:键与类型绑定极强,无类型歧义;缺点:枚举写法稍显繁琐,调用时需传入类型本身。

是否需要放弃该实现思路?

完全不需要。如果追求简单易用、低维护成本,方案1是最优选择;若需一定扩展性,方案2或3可满足需求。这些实现都能解决“键与返回类型匹配”的核心问题,复杂度完全可控,无需因初期泛型困惑就放弃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 06:24:55