我用的是泛型,设置了一个nil值,但是结果是`nil == nil`是false。如何解决这个问题呢?

I use the generic type and set a nil value, but the result is `nil == nil` is false. How to solve this problem?

代码将打印值为 nil,但 value == nil 为 false。我该如何为它做点什么。

import Foundation

struct Token: Codable {
    var token: String
    var refreshToken: String
}

class User {

    @Storage(key: "User.Name.Token", defaultValue: Token(token: "testToken", refreshToken: "TestRefreshToken"))
    var token: Token?

    var isLogined: Bool {
        return token != nil
    }

    static let shared = User()
    private init() { }

    func logout() {
        token = nil
    }
}

@propertyWrapper
struct Storage<T: Codable> {
    private let key: String
    private let defaultValue: ()->T

    init(key: String, defaultValue: @escaping @autoclosure ()->T) {
        self.key = key
        self.defaultValue = defaultValue
    }

    var wrappedValue: T {
        get {
            guard let data = UserDefaults.standard.object(forKey: key) as? Data,
                  let value = try? JSONDecoder().decode(T.self, from: data) else {
                return defaultValue()
            }
            print( "value is \(value)  " +  " but  \(value == nil)")
            return value
        }

        set {
            guard newValue != nil else {
                UserDefaults.standard.removeObject(forKey: key)
                return
            }
            let data = try? JSONEncoder().encode(newValue)
            UserDefaults.standard.set(data, forKey: key)
        }
    }
}

print( "before \(User.shared.token)")
User.shared.logout()
print( "after \(User.shared.token)")

如果您希望包装值是可选的,您可以将其更改为:

var wrappedValue: T? { // <- make it optional
    get {
        guard let data = UserDefaults.standard.object(forKey: key) as? Data,
            let value = try? JSONDecoder().decode(T.self, from: data) else {
            return defaultValue()
        }
        // after guard-let the `value` will never be `nil`
        print("value is \(value)")
        return value
    }

    set {
        guard newValue != nil else {
            UserDefaults.standard.removeObject(forKey: key)
            return
        }
        let data = try? JSONEncoder().encode(newValue)
        UserDefaults.standard.set(data, forKey: key)
    }
}

注意这里value如果解码失败可以nil:

let value = try? JSONDecoder().decode(T.self, from: data)

但是如果你使用 guard-let 它会 return defaultValue() 如果值是 nil 并且永远不会超过 guard 块:

guard let value = try? JSONDecoder().decode(T.self, from: data) else {
    return defaultValue()
}
// here `value` can't be `nil`