英文:
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>
后面的 RawValue
和 init(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 '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
}
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<RawRepresentable>
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<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
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<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
}
You can just remove it and have the type be declared by the resulting property.
let res:Test23? = getUDValue("test", .test)
or
let res:Test23 = getUDValue("test", .test)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论