无合并:在 Swift 中使用可选类型作为默认值
nil coalescing: Using optional types as default value in Swift
我有这个:
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 = [=14=] as? [String: AnyObject] ?? {
println(result)
}
}
这取决于您所说的 "matter" 是什么意思。它会起作用。它可能不是你想要的 - 如果 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 可能比您想知道的更多,但简而言之:结果必须在编译时固定为特定类型,而不管 a
和b
处于运行时。由于 b
是可选的,因此 a!
隐式包装在可选中以使两种类型兼容。这么说吧——如果结果不是可选的,而 b
是 nil
,结果会是什么?
请记住,您可以链接 ??
,这样您就可以在末尾放置第三个非可选值,这将使结果成为非可选值。
这是零合并。
如果 b 不是可选的:
a ?? b
将 return 展开 a,如果 a 不为零。如果 a 为零,它将 return b.
如果 b 是非可选的:
a ?? b
将 return a,如果 a 不为零。如果 a 为零,它将 return b.
这段代码可以工作。
但是由于您无论如何都是单独捕获错误的,所以我建议将 responseDictionary 保留为 nil 而不是将其分配给 error.localDescription
(如果失败)。这只是更好的设计。如下所示。
let responseDictionary: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: .allZeros, error:&error)
我有这个:
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 = [=14=] as? [String: AnyObject] ?? {
println(result)
}
}
这取决于您所说的 "matter" 是什么意思。它会起作用。它可能不是你想要的 - 如果 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 可能比您想知道的更多,但简而言之:结果必须在编译时固定为特定类型,而不管 a
和b
处于运行时。由于 b
是可选的,因此 a!
隐式包装在可选中以使两种类型兼容。这么说吧——如果结果不是可选的,而 b
是 nil
,结果会是什么?
请记住,您可以链接 ??
,这样您就可以在末尾放置第三个非可选值,这将使结果成为非可选值。
这是零合并。
如果 b 不是可选的:
a ?? b
将 return 展开 a,如果 a 不为零。如果 a 为零,它将 return b.
如果 b 是非可选的:
a ?? b
将 return a,如果 a 不为零。如果 a 为零,它将 return b.
这段代码可以工作。
但是由于您无论如何都是单独捕获错误的,所以我建议将 responseDictionary 保留为 nil 而不是将其分配给 error.localDescription
(如果失败)。这只是更好的设计。如下所示。
let responseDictionary: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: .allZeros, error:&error)