You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何SwiftUI结构体无法在View外部初始化?求技术解释

问题:结构体初始化必须放在View的body中才能运行的原因

我无法让Book结构体完成初始化,除非把它移到ContentView的body里,求解释原因。

无法运行的代码

struct ContentView: View {
    var sampleText = "This is sample text"
    var booksArray = ["Book 1", "Book 2", "Book 3"]
    let aBook = Book(passage: sampleText, books: booksArray)
    
    var body: some View {
        ScrollView(.vertical, showsIndicators: false, content: {
            VStack {
                Text(aBook.passage)
                    .frame(width: 350, height: .infinity, alignment: .center)
                    .kerning(1)
            }
        })
    }
}

可以运行的代码

struct ContentView: View {
    var sampleText = "This is sample text"
    var booksArray = ["Book 1", "Book 2", "Book 3"]
    
    var body: some View {
        let aBook = Book(passage: sampleText, books: booksArray)
        ScrollView(.vertical, showsIndicators: false, content: {
            VStack {
                Text(aBook.passage)
                    .frame(width: 350, height: .infinity, alignment: .center)
                    .kerning(1)
            }
        })
    }
}

原因解释

核心规则:Swift结构体存储属性的初始化限制

  • 顶层属性初始化不能依赖其他存储属性:在Swift结构体的顶层(直接定义在结构体内部,不属于任何方法或计算属性的位置),初始化存储属性时,不能使用其他存储属性的值。这是因为结构体要求所有存储属性在初始化完成时必须处于有效状态,而顶层属性的初始化顺序是不确定的——当你尝试用sampleText和booksArray初始化aBook时,这两个属性可能还没完成初始化,编译器会直接报错。

  • 计算属性body的时机安全:body是View协议要求的计算属性,当body被调用时,ContentView的所有顶层存储属性(sampleText、booksArray)已经完成初始化,它们的值是确定且有效的,此时用它们来创建aBook完全符合Swift的初始化规则。

简单说就是:顶层不能用还没初始化好的属性创建新存储属性,而计算属性内部可以访问已经初始化完成的所有属性。

内容的提问来源于stack exchange,提问作者tryingtocode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 08:08:30