【问题标题】:nil coalescing: Using optional types as default value in Swiftnil coalescing:在 Swift 中使用可选类型作为默认值
【发布时间】:2015-03-02 06:38:11
【问题描述】:

我有这个:

let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)

        dispatch_async(queue, {
            if let data = NSURLConnection.sendSynchronousRequest(self.buildRequestForVenueLocation(location, identifier), returningResponse: &response, error: &error) {
                let responseDictionary: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: .allZeros, error:&error) ?? error?.localizedDescription
                dispatch_async(dispatch_get_main_queue(), {
                    completion(venues: responseDictionary, error: error)
                })
            } else {
                println("There was a problem with the request...")
            }
        })

我的问题特别是关于这条线:

let responseDictionary: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: .allZeros, error:&error) ?? error?.localizedDescription

nil coalescing 的用法正确吗?

根据 Apple 的文档,这是等效的:

a != nil ? a! : b

如果 a 为 nil,则返回 b,但如果 b 是可选类型,是否重要?

编辑

如果有人想知道,这是我调用函数时的样子:

v.performVenueLocationRequest(l.location, identifier: "4d4b7105d754a06374d81259") {
        if let result = $0 as? [String: AnyObject] ?? $1 {
            println(result)
        }
    }

【问题讨论】:

    标签: swift optional null-coalescing


    【解决方案1】:

    这取决于你所说的“物质”是什么意思。它会起作用的。它可能不是你想要的——如果b 是可选的,那么结果也是可选的,即即使a 有一个值,它仍然不会被解包:

    let a: Int? = 2
    let b: Int? = 3
    let c = i ?? j
    // c is {Some 2}
    

    对比:

    let i: Int? = nil
    let j: Int? = 3
    let k = i ?? j
    // k is {Some 3}
    

    查看this article 可能比您想知道的更多,但简而言之:无论ab 在运行时的值是什么,结果都必须在编译时固定为特定类型.由于b 是可选的,a! 隐式包装在可选中以使两种类型兼容。这么说吧——如果结果不是可选的,bnil,结果会是什么?

    请记住,您可以链接??,这样您就可以在末尾添加第三个值,该值不是可选的,这会使结果成为非可选的。

    【讨论】:

    • 知道了,谢谢!但在我的情况下 - 传递给闭包的字典无论如何都需要两个可选参数,然后我在实际的函数调用中展开
    【解决方案2】:

    这是零合并。

    如果 b 不是可选的:
    a ?? b 将返回未包装的 a,如果 a 不为零。如果 a 为 nil,则返回 b。

    如果 b 不是可选的:如果 a 不为零,
    a ?? b 将返回 a。如果 a 为 nil,则返回 b。

    此代码将起作用。 但由于无论如何您都是单独捕获错误,我建议将 responseDictionary 保留为 nil 而不是将其分配给 error.localDescription(如果失败)。这只是更好的设计。如下所示。

    let responseDictionary: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: .allZeros, error:&error)
    

    【讨论】:

    • “这是 nil 合并。如果 a 不是 nil,a ?? b 将返回展开的 a。如果 a 是 nil,它将返回 b。”如果b 是可选的,则不会...
    • 哦,谢谢。我不知道如果 b 是可选的会发生什么。但有道理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-08
    • 2017-10-11
    • 2017-09-05
    • 2017-12-05
    • 1970-01-01
    • 1970-01-01
    • 2016-06-20
    相关资源
    最近更新 更多