【问题标题】:Synthesised init for a struct with @propertyWrapper members具有 @propertyWrapper 成员的结构的合成初始化
【发布时间】:2020-04-20 17:39:49
【问题描述】:

SwiftUI 的 @State 属性包装器有什么魔力,这意味着我可以做到这一点?:

struct A {    
    @State var s: String
}

let a = A(s: "string") //uses a synthesised init for `A` which allows me to init A with the underlying type of `A.s` - a `string`

而如果我自己滚动@propertyWrapper,我不能?

@propertyWrapper
struct Prop<Value> {
    var value: Value
    var wrappedValue: Value {
        get { value }
        set { value = newValue }
    }
}

struct B {
    @Prop var s: String
}

let b = B(s: "string") // Compiler error: `Cannot convert value of type 'String' to expected argument type 'Prop<String>'`
let b = B(s: Prop(value: "string")) // Works, but is ugly

【问题讨论】:

    标签: swift swiftui swift5.1


    【解决方案1】:

    如文档所述:

    ...您可以让编译器为您执行此操作,就像使用 @State 一样 - 只需在您的属性包装器定义中添加一个特定的魔法 init(wrappedValue:)

    @propertyWrapper
    struct Prop<Value> {
        var value: Value
        var wrappedValue: Value {
            get { value }
            set { value = newValue }
        }
    
        // magic sauce
        init(wrappedValue: Value) {
            self.value = wrappedValue
        }
    }
    
    struct B {
        @Prop var s: String
    }
    
    let b = B(s: "string") // Now works
    

    顺便说一句,这还允许您在结构定义中为包装的属性分配默认值:

    struct B {
        @Prop var s: String = "default value" // Works now; would have thrown a compiler error before
    }
    

    【讨论】:

    • 记录在案的here
    猜你喜欢
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    相关资源
    最近更新 更多