Getting error with previously supported Optional type requirements on a function declaration (same-type, error in Swift 6)

huangapple go评论66阅读模式
英文:

Getting error with previously supported Optional type requirements on a function declaration (same-type, error in Swift 6)

问题

这是您提供的代码的中文翻译:

这部分目前可以工作,但在 xcode-beta 中出现了警告:

“相同类型的要求使泛型参数 'Value' 变为非泛型;这在 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 初始化程序中获取了这个结构: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 等。

英文:

This currently works, but in xcode-beta it is now showing a warning:

Same-type requirement makes generic parameter &#39;Value&#39; non-generic; this is an error in Swift 6

func getUDValue&lt;Value, R&gt;(_ key: String, _ defaultValue: Value) -&gt; 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
}

I understand what it is saying, but trying to remove the Value == R?, R: RawRepresentable has proven difficult as the R is needed to access the RawValue and init(rawValue:) behind the Optional&lt;RawRepresentable&gt;

Interestingly enough, I got this structure from Apple's own AppStorage initializer for optional RawRepresentables: https://developer.apple.com/documentation/swiftui/appstorage/init(_:store:)-6aj8x

If this is soon to be an error, does anyone know how to accomplish this in the new world?

Update:

My current solution was to move these methods into a struct that provides the generic <Value> label. See here:

private struct UserDefaultsWrapper&lt;Value&gt; {
    static nonisolated func getValue(_ key: String, _ defaultValue: Value) -&gt; 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&lt;R&gt;(_ key: String, _ defaultValue: Value) -&gt; 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) -&gt; Value
    where Value: UserDefaultsPropertyListValue
    {
        return UserDefaults.standard.object(forKey: key) as? Value ?? defaultValue
    }

    static nonisolated func getValue&lt;R&gt;(_ key: String, _ defaultValue: Value) -&gt; 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&lt;R&gt;(_ 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&lt;R&gt;(_ key: String, _ newValue: Value)
    where Value == R?, R: UserDefaultsPropertyListValue
    {
        UserDefaults.standard.set(newValue, forKey: key)
    }
}

UserDefaultsPropertyListValue is a protocol used to extend supported non-RawRepresentable types, e.g. Int, Bool, String, etc.

答案1

得分: 1

我认为在这种情况下,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)
英文:

I think Value is redundant in this case.

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

You can just remove it and have the type be declared by the resulting property.

let res:Test23? = getUDValue(&quot;test&quot;, .test)

or

let res:Test23 = getUDValue(&quot;test&quot;, .test)

huangapple
  • 本文由 发表于 2023年6月22日 00:05:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76525198.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定