对于常规propertyWrapper,如何检测类型是可选的

我正在为UserDefaults创建一个属性包装器。

我要实现的目标是:

  • 为属性设置非nil值会将其存储在用户默认设置中。
  • 设置nil将从UserDefault中删除该对象。

但是下面的代码会引发编译器错误

  

用于条件绑定的初始化程序必须具有可选类型,而不是'T'

@propertyWrapper
struct UserDefault<T> {
    let key: String
    let defaultvalue: T

    init(_ key: String,defaultvalue: T) {
        self.key = key
        self.defaultvalue = defaultvalue
    }

    var wrappedValue: T {
        get { UserDefaults.standard.value(forKey: key) as? T ?? defaultvalue }
        set {
            if let newValue = newValue {
                UserDefaults.standard.setvalue(newValue,forKey: key)
            } else {
                UserDefaults.standard.removeObject(forKey: key)
            }
        }
    }
}

// Declaration
@UserDefault("key",defaultvalue: nil)
static var newUserDefaultvalue: String

有什么方法可以识别T是可选的吗?因为我可以从UserDefaults中删除密钥。如果不能达到预期的输出效果?

hyx_su 回答:对于常规propertyWrapper,如何检测类型是可选的

您的代码中有2个问题:

1)在您的情况下,wrappedValuedefaultValue应该是可选的:

struct UserDefault<T> {
  let key: String
  let defaultValue: T? // defaultValue should be optional

  // defaultValue should be optional
  init(_ key: String,defaultValue: T?) {
    self.key = key
    self.defaultValue = defaultValue
  }

  // wrappedValue should also be optional
  var wrappedValue: T? {
    get { UserDefaults.standard.value(forKey: key) as? T ?? defaultValue }
    set {
      if let newValue = newValue {
        UserDefaults.standard.setValue(newValue,forKey: key)
      } else {
        UserDefaults.standard.removeObject(forKey: key)
      }
    }
  }
}

2)如果使用nil defaultValue进行初始化,则应为编译器指定类型T

// Type T should be expicitly specified. For example as String
let valueWithNilDefault = UserDefault<String>("key",defaultValue: nil)

// Type T will be determined during compile time as Int
let valueWithDefault = UserDefault("key",defaultValue: 15)
本文链接:https://www.f2er.com/3123894.html

大家都在问