Swift 6中函数Optional类型同类型要求报错的解决方案问询
适配Swift 6:解决泛型参数非泛型警告问题
问题背景
现有一段从UserDefaults读取值的代码可正常运行,但在Xcode测试版中触发警告:Same-type requirement makes generic parameter 'Value' non-generic; this is an error in Swift 6
原代码如下:
func getUDValue<Value, R>(_ key: String, _ defaultValue: Value) -> Value where Value == R?, R: RawRepresentable { guard let rawValue = UserDefaults.standard.object(forKey: key) as? R.RawValue else { return defaultValue } return R(rawValue: rawValue) ?? defaultValue }
这段代码用于读取可选的RawRepresentable类型值,通过Value == R?的约束关联可选类型与底层的RawRepresentable类型R,从而访问R的RawValue和init(rawValue:)方法。但Swift 6会将这种“让泛型参数失去泛型特性”的写法判定为错误,而直接移除该约束又无法实现原有逻辑。
临时解决方案
将相关读写方法封装到泛型结构体中,通过重载方法分别处理非可选/可选的RawRepresentable类型、非可选/可选的UserDefaultsPropertyListValue类型:
private struct UserDefaultsWrapper<Value> { static nonisolated func getValue(_ key: String, _ defaultValue: Value) -> Value where Value: RawRepresentable { guard let rawValue = UserDefaults.standard.object(forKey: key) as? Value.RawValue else { return defaultValue } return Value(rawValue: rawValue) ?? defaultValue } static nonisolated func getValue<R>(_ key: String, _ defaultValue: Value) -> Value where Value == R?, R: RawRepresentable { guard let rawValue = UserDefaults.standard.object(forKey: key) as? R.RawValue else { return defaultValue } return R(rawValue: rawValue) ?? defaultValue } static nonisolated func getValue(_ key: String, _ defaultValue: Value) -> Value where Value: UserDefaultsPropertyListValue { return UserDefaults.standard.object(forKey: key) as? Value ?? defaultValue } static nonisolated func getValue<R>(_ key: String, _ defaultValue: Value) -> Value where Value == R?, R: UserDefaultsPropertyListValue { return UserDefaults.standard.object(forKey: key) as? R ?? defaultValue } static nonisolated func setValue(_ key: String, _ newValue: Value) where Value: RawRepresentable { UserDefaults.standard.set(newValue.rawValue, forKey: key) } static nonisolated func setValue<R>(_ key: String, _ newValue: Value) where Value == R?, R: RawRepresentable { UserDefaults.standard.set(newValue?.rawValue, forKey: key) } static nonisolated func setValue(_ key: String, _ newValue: Value) where Value: UserDefaultsPropertyListValue { UserDefaults.standard.set(newValue, forKey: key) } static nonisolated func setValue<R>(_ key: String, _ newValue: Value) where Value == R?, R: UserDefaultsPropertyListValue { UserDefaults.standard.set(newValue, forKey: key) } }
其中UserDefaultsPropertyListValue是自定义协议,用于扩展支持Int、Bool、String等非RawRepresentable的UserDefaults可存储类型。
内容的提问来源于stack exchange,提问作者Doghound
相关产品推荐
相关产品推荐

