假错误?`在初始化之前使用的变量` 在 init() 中初始化期间

Tho*_*n74 4 struct initialization init swift swiftui

抱歉举了这个毫无意义的例子。试图简化它,仍然不明白\xe2\x80\x99s发生了什么。以下给了我Variable \'self.greeting\' used before being initialized

\n
struct MyView: View {\n    @State var greeting: String\n    var length = Measurement<UnitLength>(value: 5, unit: UnitLength.miles)\n    init() {\n        greeting = "Hello, World!" // Variable \'self.greeting\' used before being initialized\n    }\n    var body: some View {\n        Text(greeting)\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

虽然这工作正常(var length不同;否则相同):

\n
struct MyView: View {\n    @State var greeting: String\n    var length = 5 // now Int\n    init() {\n        greeting = "Hello, World!"\n    }\n    var body: some View {\n        Text(greeting)\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

另外,这是有效的(这里我删除了@State):

\n
struct MyView: View {\n    var greeting: String // @State removed\n    var length = Measurement<UnitLength>(value: 5, unit: UnitLength.miles)\n    init() {\n        greeting = "Hello, World!"\n    }\n    var body: some View {\n        Text(greeting)\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  • greeting 如果编译器希望我先 初始化,init()那会在哪里?preinit()
  • \n
  • 为什么它认为greeting\xe2\x80\x9cused\xe2\x80\x9d 未初始化,而实际上我在这里初始化它?
  • \n
  • 有没有不同的方法来初始化 @State 变量?如果是这样,为什么当不相关的 varlength是 ofInt而不是 时它会起作用Measurement
  • \n
\n

bat*_*str 7

这段代码:

@State var greeting: String
Run Code Online (Sandbox Code Playgroud)

在幕后创建一个支持变量:

let _greeting: State<String>
Run Code Online (Sandbox Code Playgroud)

如果你想在 init() 中自己初始化它,你可以这样做:

init() {
    _greeting = new State<String>(initialValue: "Hello, World!")
}
Run Code Online (Sandbox Code Playgroud)

但由于你有一个常量,所以像这样设置它会更简单:

@State var greeting: String = "Hello, World!"
Run Code Online (Sandbox Code Playgroud)

第三个变体有效,因为没有 @State 就没有魔法。

第一个选项不起作用,因为代码被翻译为:

init() {
    self._greeting.wrappedValue = "Hello, World!"
}
Run Code Online (Sandbox Code Playgroud)

并且_greeting此时尚未初始化(未指定初始值)。是的,该错误具有误导性。

我不知道为什么第二个版本有效。未指定初始值,并且字符串没有隐式默认值。也许这是 iOS 15 SwiftUI 的一项新功能,应该可以使用,但由于某些限制,并非在所有情况下都可以使用?

PS 有类似“preinit”的东西:所有分配有某些表达式的属性都length = Measurement<UnitLength>(...)在 init 之前运行,但无法访问它,它是内部的。