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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:23:10