一切都在游泳,除非我做一个随机的字符串,例如" fds",我如何才能正确有效地使用警卫来防止这种错误?
init(weatherData: [String: AnyObject]) {
city = weatherData["name"] as! String
let weatherDict = weatherData["weather"]![0] as! [String: AnyObject]
description = weatherDict["description"] as! String
icon = weatherDict["icon"] as! String
let mainDict = weatherData["main"] as! [String: AnyObject]
currentTemp = mainDict["temp"] as! Double
humidity = mainDict["humidity"] as! Int
let windDict = weatherData["wind"] as! [String: AnyObject]
windSpeed = windDict["speed"] as! Double
}
答案 0 :(得分:10)
我如何正确有效地使用警卫来防止此类错误?
你为什么要这样?如果来电者没有递给你"name"
键并且是一个字符串的字典,那么你就无法初始化city
。你希望崩溃。
如果您希望在没有实际崩溃的情况下摆脱这种情况,那么如果字典不包含所需数据,则将其设置为 failable 初始化程序并失败(返回nil
)。这有效地推动了崩溃到调用者的危险,因为结果将是一个可选的nil
,并且调用者必须检查它。
init?(weatherData: [String: AnyObject]) {
guard let city = weatherData["name"] as? String else {return nil}
self.city = city
// ... and so on ...
}
但我所做的不是那些事情。我会将初始化程序重写为init(city:description:icon:currentTemp:humidity:windSpeed:)
并强制调用者将字典解析为所需的数据。这样,如果数据不存在,我们甚至不会尝试首先初始化这个类。我的论点是,解析字典是调用者的工作; 这个类应该不知道从互联网上拉出的一些复杂字典的结构(或者无论来源是什么)。