获取函数声明中先前支持的可选类型要求的错误(相同类型,Swift 6中的错误)

w7t8yxp5  于 11个月前  发布在  Swift
关注(0)|答案(1)|浏览(74)

这目前是有效的,但在xcode-beta中,它现在显示一个警告:
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
}

我明白它的意思,但事实证明,删除Value == R?, R: RawRepresentable很困难,因为需要R才能访问Optional<RawRepresentable>后面的RawValueinit(rawValue:)
有趣的是,我从苹果自己的AppStorage初始化器中获得了这个结构,用于可选的RawRepresentables:https://developer.apple.com/documentation/swiftui/appstorage/init(_:store:)-6aj8x
如果这很快就会成为一个错误,有没有人知道如何在新世界中完成这一点?

更新:

我目前的解决方案是将这些方法移动到一个提供泛型标签的结构中。请看这里:

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是一个用于扩展支持的非RawRepresentable类型的协议,例如Int、Bool、String等

kxeu7u2r

kxeu7u2r1#

我认为Value在这种情况下是多余的。

func getUDValue<R>(_ key: String, _ defaultValue: R) -> R
where R: RawRepresentable
{
    guard let rawValue = UserDefaults.standard.object(forKey: key) as? R.RawValue else {
        return defaultValue
    }
    return R(rawValue: rawValue) ?? defaultValue
}

您可以只移除它,并让结果属性声明该类型。

let res:Test23? = getUDValue("test", .test)

let res:Test23 = getUDValue("test", .test)

相关问题