SwiftUI中初始化OpenWeather API模型变量报错,求解决方案
问题原因与解决方案
错误原因
当结构体遵循Codable协议时,Swift会自动生成仅接受Decoder参数的初始化器(init(from decoder: Decoder)),但不会自动生成无参的默认初始化器——除非结构体的所有属性都有默认值,或者你手动实现无参初始化器。
直接调用Weather()或WeatherResponse()时,Swift找不到对应的无参初始化器,因此报错要求传入Decoder参数。而[Weather]()能正常工作,是因为Swift数组本身自带空集合的默认初始化器,与元素类型的初始化器无关。
解决方案
有两种常用解决方式,按需选择:
方式一:给结构体属性添加默认值
给结构体所有属性设置默认值,Swift会自动生成无参初始化器,即可直接创建实例:
修改Weather结构体:
struct Weather: Hashable, Codable { var main: String = "" var description: String = "" }
修改WeatherResponse结构体:
struct WeatherResponse: Codable { var weather: [Weather] = [] var name: String = "" }
之后即可正常声明状态变量:
@State var weatherForcast = WeatherResponse() // 或 @State var singleWeather = Weather()
方式二:手动实现无参初始化器
若不想给属性设置默认值,可手动添加无参初始化器,同时需显式实现Codable的解码初始化器(自定义初始化器会覆盖自动生成的实现):
修改Weather结构体:
struct Weather: Hashable, Codable { var main: String var description: String // 手动添加无参初始化器 init() { main = "" description = "" } // 显式实现Codable的解码初始化器 init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) main = try container.decode(String.self, forKey: .main) description = try container.decode(String.self, forKey: .description) } }
修改WeatherResponse结构体:
struct WeatherResponse: Codable { var weather: [Weather] var name: String // 手动添加无参初始化器 init() { weather = [] name = "" } // 显式实现Codable的解码初始化器 init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) weather = try container.decode([Weather].self, forKey: .weather) name = try container.decode(String.self, forKey: .name) } }
这样也能正常创建Weather()或WeatherResponse()实例。
内容的提问来源于stack exchange,提问作者Shiloni
相关产品推荐
相关产品推荐

