【问题标题】:Using guard in Swift struct does not initialize all properties在 Swift 结构中使用守卫不会初始化所有属性
【发布时间】:2015-11-25 02:31:24
【问题描述】:

对于 示例 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,我尝试使用如下所示的保护语句进行可选链接:

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 中的可选链接方法有效,但它要求保护语句中的所有检查都为真。如果其中一个变量不在 JSON 数据中,那么整个语句将是错误的。例如,如果tzs 不在jsonDict 中,那么所有属性都将为“否”。

我正在 Playground 中运行所有这些代码(如果重要的话)。

如果 JSON 字典中没有一个或多个属性,我如何获得 示例 A 来初始化 struct

【问题讨论】:

    标签: json swift struct swift2 optional


    【解决方案1】:

    使用nil coalescing operator (??):

    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"
    }
    

    nil 合并运算符 (a ?? b) 解开可选的 a 如果它 包含一个值,如果 a 为 nil,则返回默认值 b。这 表达式 a 始终是可选类型。表达式 b 必须 匹配存储在 a 中的类型。

    或者,当然,当您在其他地方访问它们时(例如,当您向用户显示此位置时),如果可选项为 nil,您可以将属性设置为可选并替换“none”字符串。

    【讨论】:

    • guardif-let 方法在这种情况下不合适。似乎?? 更简洁。另外,为什么要使用name 而不是self.name
    • @GavinWiggins 你本可以使用if-let-else,这会让编译器足够高兴,但这更简洁。与实例方法一样,您不必使用self 来引用初始化程序中的当前实例。然而,一些开发人员更喜欢它。
    猜你喜欢
    • 2020-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多