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
相关产品推荐
相关产品推荐

