延迟语句和 return 之前的语句有什么区别?
What's the difference between a defer statement and a statement right just before return?
这有什么区别:
_ = navigationController?.popViewController(animated: true)
defer {
let rootVC = navigationController?.topViewController as? RootViewVC
rootVC?.openLink(url: url)
}
return
还有这个:
_ = navigationController?.popViewController(animated: true)
let rootVC = navigationController?.topViewController as? RootViewVC
rootVC?.openLink(url: url)
return
Apple 的 swift 指南说:“您使用 defer 语句在代码执行离开当前代码块之前执行一组语句。 ”,但我还是不太明白。
在你的示例中实际上没有区别,但请看这个:
func foo(url: URL) -> Int
let fileDescriptor : CInt = open(url.path, O_EVTONLY);
defer {
close(fileDescriptor)
}
guard let bar = something1() else { return 1 }
guard let baz = something2() else { return 2 }
doSomethingElse(bar, baz)
return 3
}
close(fileDescriptor)
总是执行,不管函数returns.
在哪一行
使用 defer
可以避免在函数结束时进行条件清理。
考虑这个例子:
class Demo {
var a : String
init(_ a:String) {
self.a = a
}
func finish() {
print("Finishing \(a)")
}
}
func play(_ n:Int) {
let x = Demo("x")
defer { x.finish() }
if (n < 2) {return}
let y = Demo("y")
defer { y.finish() }
if (n < 3) {return}
let z = Demo("z")
defer { z.finish() }
}
play(1)
play(2)
play(3)
函数 play
根据其参数创建一个、两个或三个 Demo
对象,并在 运行 的末尾对它们调用 finish
。如果中间的函数 returns,defer
语句不会执行,并且不会为从未创建的对象调用 finish
。
对此的替代方法需要使用选项:
func play(_ n:Int) {
var x:Demo? = nil
var y:Demo? = nil
var z:Demo? = nil
x = Demo("x")
if (n >= 2) {
y = Demo("y")
}
if (n >= 3) {
z = Demo("z")
}
x?.finish()
y?.finish()
z?.finish()
}
这种方法将所有声明放在顶部,并强制您稍后解包可选值。另一方面,带有 defer
的代码允许您在执行初始化的代码附近编写清理代码。
What's the difference between a defer statement and a statement right just before return?
世界上所有的差异。 defer
语句在 return 之后执行!这使您可以完成其他方法无法完成的事情。
例如,您可以 return 一个值,然后 更改该值。 Apple 经常使用这个技巧;例如,这里是序列文档中的代码,展示了如何编写自定义序列:
struct Countdown: Sequence, IteratorProtocol {
var count: Int
mutating func next() -> Int? {
if count == 0 {
return nil
} else {
defer { count -= 1 }
return count
}
}
}
如果你把它写成
count -= 1
return count
...它会坏掉;我们不想递减 count
然后 return 它,我们想 return count
然后递减它。
此外,正如已经指出的,无论如何退出,defer
语句都会执行。无论您退出当前 scope,它都有效,这可能根本不涉及 return
; defer
适用于函数体、while 块、if 结构、do 块等。单个 return
不是退出此类范围的唯一方法!你的方法中可能有多个 return
,and/or 你可能会抛出一个错误,and/or 你可能有一个 break
,等等,或者你可能只是自然到达范围的最后一行; defer
在所有可能的情况下都会执行。编写相同的代码 "by hand" 以覆盖所有可能的出口,这很容易出错。
defer 语句用于恰好在执行离开最近范围之前执行一段代码。
例如:
func defer() {
print("Beginning")
var value: String?
defer {
if let v = value {
print("Ending execution of \(v)")
}
}
value = "defer function"
print("Ending")
}
将打印的第一行是:开始
将打印的第二行是:结束
打印的最后一行是:Ending execution of defer function。
这有什么区别:
_ = navigationController?.popViewController(animated: true)
defer {
let rootVC = navigationController?.topViewController as? RootViewVC
rootVC?.openLink(url: url)
}
return
还有这个:
_ = navigationController?.popViewController(animated: true)
let rootVC = navigationController?.topViewController as? RootViewVC
rootVC?.openLink(url: url)
return
Apple 的 swift 指南说:“您使用 defer 语句在代码执行离开当前代码块之前执行一组语句。 ”,但我还是不太明白。
在你的示例中实际上没有区别,但请看这个:
func foo(url: URL) -> Int
let fileDescriptor : CInt = open(url.path, O_EVTONLY);
defer {
close(fileDescriptor)
}
guard let bar = something1() else { return 1 }
guard let baz = something2() else { return 2 }
doSomethingElse(bar, baz)
return 3
}
close(fileDescriptor)
总是执行,不管函数returns.
使用 defer
可以避免在函数结束时进行条件清理。
考虑这个例子:
class Demo {
var a : String
init(_ a:String) {
self.a = a
}
func finish() {
print("Finishing \(a)")
}
}
func play(_ n:Int) {
let x = Demo("x")
defer { x.finish() }
if (n < 2) {return}
let y = Demo("y")
defer { y.finish() }
if (n < 3) {return}
let z = Demo("z")
defer { z.finish() }
}
play(1)
play(2)
play(3)
函数 play
根据其参数创建一个、两个或三个 Demo
对象,并在 运行 的末尾对它们调用 finish
。如果中间的函数 returns,defer
语句不会执行,并且不会为从未创建的对象调用 finish
。
对此的替代方法需要使用选项:
func play(_ n:Int) {
var x:Demo? = nil
var y:Demo? = nil
var z:Demo? = nil
x = Demo("x")
if (n >= 2) {
y = Demo("y")
}
if (n >= 3) {
z = Demo("z")
}
x?.finish()
y?.finish()
z?.finish()
}
这种方法将所有声明放在顶部,并强制您稍后解包可选值。另一方面,带有 defer
的代码允许您在执行初始化的代码附近编写清理代码。
What's the difference between a defer statement and a statement right just before return?
世界上所有的差异。 defer
语句在 return 之后执行!这使您可以完成其他方法无法完成的事情。
例如,您可以 return 一个值,然后 更改该值。 Apple 经常使用这个技巧;例如,这里是序列文档中的代码,展示了如何编写自定义序列:
struct Countdown: Sequence, IteratorProtocol {
var count: Int
mutating func next() -> Int? {
if count == 0 {
return nil
} else {
defer { count -= 1 }
return count
}
}
}
如果你把它写成
count -= 1
return count
...它会坏掉;我们不想递减 count
然后 return 它,我们想 return count
然后递减它。
此外,正如已经指出的,无论如何退出,defer
语句都会执行。无论您退出当前 scope,它都有效,这可能根本不涉及 return
; defer
适用于函数体、while 块、if 结构、do 块等。单个 return
不是退出此类范围的唯一方法!你的方法中可能有多个 return
,and/or 你可能会抛出一个错误,and/or 你可能有一个 break
,等等,或者你可能只是自然到达范围的最后一行; defer
在所有可能的情况下都会执行。编写相同的代码 "by hand" 以覆盖所有可能的出口,这很容易出错。
defer 语句用于恰好在执行离开最近范围之前执行一段代码。
例如:
func defer() {
print("Beginning")
var value: String?
defer {
if let v = value {
print("Ending execution of \(v)")
}
}
value = "defer function"
print("Ending")
}
将打印的第一行是:开始
将打印的第二行是:结束
打印的最后一行是:Ending execution of defer function。