Json 在Swift结构中使用guard不会初始化所有属性
对于示例A,我在Swift中为Json 在Swift结构中使用guard不会初始化所有属性,json,swift,struct,swift2,optional,Json,Swift,Struct,Swift2,Optional,对于示例A,我在Swift中为struct提供了以下代码: struct Location { let name: String let tzs: String let lat: String let lon: String init(jsonDict: [String: AnyObject]) { guard let name = jsonDict["name"] as? String else { self.
struct
提供了以下代码:
struct Location {
let name: String
let tzs: String
let lat: String
let lon: String
init(jsonDict: [String: AnyObject]) {
guard let name = jsonDict["name"] as? String else {
self.name = "none"
return
}
guard let tzs = jsonDict["tzs"] as? String else {
self.tzs = "none"
return
}
guard let lat = jsonDict["lat"] as? String else {
self.lat = "none"
return
}
guard let lon = jsonDict["lon"] as? String else {
self.lon = "none"
return
}
self.name = name
self.tzs = tzs
self.lat = lat
self.lon = lon
}
}
属性是从解析JSON数据获得的字典中初始化的。不幸的是,代码提供了一个关于“从初始值设定项返回而不初始化所有存储属性”的警告
对于示例B我尝试了使用guard语句的可选链接,如下所示:
struct Location {
let name: String
let tzs: String
let lat: String
let lon: String
init(jsonDict: [String: AnyObject]) {
guard
let name = jsonDict["name"] as? String,
let tzs = jsonDict["tzs"] as? String,
let lat = jsonDict["lat"] as? String,
let lon = jsonDict["lon"] as? String
else {
self.name = "no"
self.tzs = "no"
self.lat = "no"
self.lon = "no"
return
}
self.name = name
self.tzs = tzs
self.lat = lat
self.lon = lon
}
}
示例B中的可选链接方法可以工作,但它要求guard语句中的所有检查都为true。如果其中一个变量不在JSON数据中,那么整个语句将为false。例如,如果tzs
不在jsonDict
中,则所有属性都将为“否”
我正在操场上运行所有这些代码(如果这很重要的话)
如果JSON字典中没有一个或多个属性,如何让示例A初始化结构
零合并运算符(a??b)将打开一个可选的a,如果它
包含一个值,如果a为nil,则返回默认值b。这个
表达式a始终是可选类型。表达式b必须
匹配存储在a中的类型
当然,您也可以将属性设置为可选的,如果在其他地方访问属性时(例如,当您向用户显示此位置时),可选值为零,则可以替换为“无”字符串。使用(??
):
零合并运算符(a??b)将打开一个可选的a,如果它
包含一个值,如果a为nil,则返回默认值b。这个
表达式a始终是可选类型。表达式b必须
匹配存储在a中的类型
当然,您也可以将属性设置为可选的,如果在其他地方访问属性时(例如,当您向用户显示此位置时)可选的字符串为零,则可以替换为“无”字符串。在这种情况下,
guard
或if let
方法不合适。似乎?
更简洁。还有,为什么要使用name
而不是self.name
?@GavinWiggins如果让else,你本可以使用,这会让编译器很高兴,但这更简洁。与实例方法一样,您不必使用self
在初始值设定项中引用当前实例。然而,一些开发人员更喜欢它。guard
或if-let
方法在这种情况下并不合适。似乎?
更简洁。还有,为什么要使用name
而不是self.name
?@GavinWiggins如果让else
,你本可以使用,这会让编译器很高兴,但这更简洁。与实例方法一样,您不必使用self
在初始值设定项中引用当前实例。然而,一些开发人员更喜欢它。
init(jsonDict: [String: AnyObject]) {
name = jsonDict["name"] as? String ?? "none"
tzs = jsonDict["tzs"] as? String ?? "none"
lat = jsonDict["lat"] as? String ?? "none"
lon = jsonDict["lon"] as? String ?? "none"
}