Open utterances-bot opened 3 years ago
你好,如下俩份代码结果不同,哪个符合预期呢?
func run() {
var a = 1
func add() -> Int {
defer {
a = a + 1
}
return a
}
a = add()
print(a) /// a = 1
}
func run() {
var a = 1
func add() -> Int {
defer {
a = a + 1
}
return a
}
add()
print(a) /// a = 2
}
都符合预期,第一个打印的 a
是 a = add()
重新赋值后的 a,而 add
返回的是 1。在返回后,a = a + 1
中左侧捕获的 a
已经不是 add
外面的 a
了。
而第二个例子打印的就是 var a = 1
时声明的 a
。
不过建议不要纠结这种东西...这个和 C 的 a++
和 ++a
有一拼了。正常人不会写这样的代码 😂
感谢回答! 是的,这个场景是基本不会出现的,做这个测试其实是为了验证一下defer的具体执行时机和对外部值引用的关系。文中描述的是不会持有外面的值,那么本质上还是同一个对象在执行指令,因此进行这个验证。 同时这个测试理论上先执行的return操作,在进行赋值之前,执行defer中的代码。通过断点可以验证确实是按照这个顺序执行的,不过不同的一点猜想是return之后的返回结果应该是被独立保存了,在之后执行defer代码的时候,a还是外面的对象,并且实际上是+1了,不过当defer结束之后,a应该才接收了被独立保存的返回值1,被重新赋值。
var a = 1
func run() {
func add() -> Int {
defer {
self.a = self.a + 1
/// step3.断点首次执行到这里 a = 2
print(self.a)
}
/// step2.断点首次执行到这里 a = 1
/// step4.断点第二次执行到这里 a = 2
return a
}
/// step1.断点首次执行到这里 a = 1
/// step5.断点第二次执行到这里 a = 2
a = add()
/// step6.断点执行到这里的时候a = 1,被赋值为之前保存的返回值
print("run -- ~~~~~~~a-\(a)") /// a = 1
}
关于 Swift defer 的正确使用 | OneV's Den
其实这篇文章的缘起是由于在对 Kingfisher 做重构的时候,因为自己对 defer 的理解不够准确,导致了一个 bug。所以想藉由这篇文章探索一下 defer 这个关键字的一些 edge case。
https://onevcat.com/2018/11/defer/