Json 在Swift结构中使用guard不会初始化所有属性

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.

对于示例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.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"
}