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

Swift开发:如何初始化Stock结构体中嵌套的MetaData类型成员变量

解决方案

你有两种常用的方式解决这个初始化问题:

方式1:填写默认的MetaData实例

你的MetaData结构体所有属性都是非可选字符串,初始化时传入空字符串作为占位值即可,后续loadData执行成功会覆盖这个默认值。将标注?????的位置替换为以下内容:

MetaData(Information: "", Symbol: "", LastRefreshed: "", OutputSize: "", TimeZone: "")

修改完成后对应代码行如下:

@Published var tmpData = Stock(metaData: MetaData(Information: "", Symbol: "", LastRefreshed: "", OutputSize: "", TimeZone: ""), timeSeriesDaily : [:])

方式2(更推荐):将tmpData改为可选类型

不需要编写无意义的默认值,直接声明tmpData为可选类型,数据加载完成后才会有有效值,还能避免界面加载阶段误用空默认值的问题。修改后的ReadData类代码如下:

class ReadData: ObservableObject  {
    // 声明为可选类型,初始值为nil
    @Published var tmpData: Stock?
    init() {
        loadData()
    }
    func loadData() {
        guard let url = Bundle.main.url(forResource: "VOO", withExtension: "json")
        else {
            print("Json file not found")
            return
        }
        let decoder = JSONDecoder()
        do {
            let data = try Data(contentsOf: url)
            self.tmpData = try decoder.decode(Stock.self, from: data)
        } catch {
            print(error)
        }
    }
}

对应调整ContentView的代码,增加数据判空逻辑避免崩溃:

struct ContentView: View {
    @ObservedObject var vooData = ReadData()
    var body: some View {
        ScrollView  {
            VStack (alignment: .leading) {
                // 数据加载完成后再渲染内容
                if let stockData = vooData.tmpData {
                    let lastYear = getOneYearAgo()
                    let filteredDict = stockData.timeSeriesDaily.filter { $0.key > lastYear }
                    let newDict = filteredDict.mapValues { Double($0.Close) }
                    let sortedNewDict = newDict.sorted { $0.key < $1.key }
                    
                    ForEach(sortedNewDict.map { ($0.key, $0.value) }, id: \.0) { keyValuePair in
                        HStack {
                            Text(keyValuePair.0)
                            // 避免Double为空时强制解包崩溃
                            if let closeValue = keyValuePair.1 {
                                Text("\(closeValue)")
                            } else {
                                Text("--")
                            }
                        }
                    }
                } else {
                    // 加载阶段显示占位提示
                    Text("数据加载中...")
                }
                Spacer()
            }
        } .frame(width: 600, height: 400, alignment: .center)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 06:54:02