这两个声明的区别是什么?哪一个更好?为什么呢?
... error = some NSError ...
1
var newUserInfo: [NSObject: NSObject] = [:]
if let tempUserInfo = error.userInfo as? [NSObject: NSObject] {
newUserInfo = tempUserInfo
}
2
var newUserInfo: [NSObject: NSObject]
if let tempUserInfo = error.userInfo as? [NSObject: NSObject] {
newUserInfo = tempUserInfo
} else {
newUserInfo = [:]
}
答案 0 :(得分:7)
从Swift 1.2开始,您现在可以将let
与延迟分配一起使用,以便您可以使用if / else版本:
let newUserInfo: [NSObject: NSObject]
if let tempUserInfo = error.userInfo as? [NSObject: NSObject] {
newUserInfo = tempUserInfo
} else {
newUserInfo = [:]
}
但是,选项1将不工作,因为有一条路径可能无法设置newUserInfo
。
(注意,从1.2b1开始,这不适用于全局变量,只适用于成员和局部变量,以防你在游乐场试试)
或者,您可以使用nil-coalescing运算符一次完成,如下所示:
let newUserInfo = (error.userInfo as? [NSObject:NSObject]) ?? [:]
编辑:Swift 1.2添加了let
的延迟分配,使选项2现在与let
一起使用,但也改变了as?
vs ??
的优先级,要求括号。
1.2之前的答案,以防您需要迁移类似的代码:
如果你问我,它们都没有特别吸引人。在这两种情况下,您都必须使用newUserInfo
声明var
,因为您没有一次性声明并分配它。
我建议:
let newUserInfo = error.userInfo as? [NSObject:NSObject] ?? [:]
答案 1 :(得分:2)
newUserInfo
中,如果执行if
分支,则分配两次。 2.在性能方面更好newUserInfo
初始化为空数组时,可以清楚地看到它。 2.使代码的可读性降低,因为您必须浏览代码才能知道它是否具有默认值newUserInfo
(例如,如果可以在多个if
语句中对其进行初始化),则应在2.中复制else
分支,这样1看起来更好所以:在解决方案中没有。 1代码更易读,但解决方案没有。 2稍微高一点。
除了使用@AirspeedVelocity解决方案(比你的更好,没有冒犯:)),我更喜欢使用可选的,将newUserInfo
设置为nil以表示没有价值 - 毕竟,那个选项是什么,不是吗?但当然这取决于您的具体需求。
答案 2 :(得分:0)
我首选的模式是:
struct TryUnrap<T> {
typealias Tryee = () -> T?
typealias Catchee = () -> T
private var tryee: Tryee
init(tryee: Tryee) {
self.tryee = tryee
}
func catch(catchee: Catchee) -> T {
if let result = tryee() {
return result
}
return catchee()
}
}
let error: NSError? = NSError()
let newUserInfo = TryUnrap {
error?.userInfo as? [NSObject : NSObject]
}.catch {
[:]
}
println("newUserInfo = \(newUserInfo)")
我更喜欢上述内容,因为我发现它对我来说更好。另请参阅Error-Handling in Swift-Language的答案4,了解使用相同模式的一般错误处理。