在Init中使用Guard?

时间:2017-02-08 22:41:53

标签: swift

一切都在游泳,除非我做一个随机的字符串,例如" fds",我如何才能正确有效地使用警卫来防止这种错误?

enter image description here

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
}

1 个答案:

答案 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:)并强制调用者将字典解析为所需的数据。这样,如果数据不存在,我们甚至不会尝试首先初始化这个类。我的论点是,解析字典是调用者的工作; 这个类应该不知道从互联网上拉出的一些复杂字典的结构(或者无论来源是什么)。