在 Swift 5.1 之前, 每當我們看到 @_SOME_ 時, 都會去 Swift.org 查找 grammar_attribute-name, 像是 @IBOutlet 或是 @escaping.
而在 Swift 5.1 之後, 我們有了 Property Wrappers Swift Evolution: SE-0258, 而這個將 Publisher 封裝起來, 透過 Compiler 轉化 原始碼, 讓程式碼更好處理與閱讀.
請參考下面原始碼:
struct UserDefulted<Value> {
    private let defaults = UserDefaults.standard
    var defaultValue:Value // 1
    private let key:String // 2
    
    var value:Value {
        get {  // 3
            return defaults.object(forKey: key) as? Value ?? defaultValue
        }
        set {
            defaults.set(newValue, forKey: key)
        }
    }
}
在這個範例中, 我們在取用值得時候並沒有想象的方便
var myValue = UserDefaulted("SOME", defaultValue: 1)
myValue.value = 1
var b:Int = myValue.value
這時, 可以使用 Property Wrappers 來強硬封裝抽象嵌套:
@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 {
            return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
        }
        set {
            UserDefaults.standard.set(newValue, forKey: key)
        }
    }
}
調用方式:
@UserDefault("Some", defaultValue: 1) var udAsset:Int
udAsset = 2
let c = udAsset
如此一來,就可以在調用時減少多餘的訊息。
@Published請看以下原始碼
@propertyWrapper struct Published<Value>
class MyFoo { // 1
    @Published var bar: String // 2
    init(bar: String) {
        self.bar = bar
    }
}
let foo = MyFoo(bar: "bar")
let barSink = foo.$bar
    .sink() {
        print("bar value: \($0)")
}
bar is String, $bar is Publisher有沒有很像CurrentValueSubject呢?
參考來源:
Property wrappers to remove boilerplate code in Swift https://www.avanderlee.com/swift/property-wrappers/