【发布时间】:2017-11-06 09:41:16
【问题描述】:
在swift documentation 的捕获值部分:
...它通过从周围的函数中捕获对 runningTotal 和 amount 的引用并在自己的函数体内使用它们来实现这一点。 ...
和
如果您创建第二个增量器,它将拥有自己存储的对新的、单独的 runningTotal 变量的引用。
所以我尝试了以下测试并得到一个结论,由于makeIncrementer(forIncrementer:) 生成的每个增量器都有自己的runningTotal 并且每个增量器记住 runningTotal 的值,所以values-capturing 相当于为闭包创建一些静态变量。但我不确定我的说法是否正确。
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}
let by10Incrementer = makeIncrementer(forIncrement: 10)
let by20Incrementer = makeIncrementer(forIncrement: 20)
for i in 0..<5 {
print(by10Incrementer())
}
print("---")
for j in 0..<5 {
print(by20Incrementer())
}
输出:
10
20
30
40
50
---
20
40
60
80
100
我原本以为by20Incrementer()的输出会从50开始,结果却是从0开始。所以每个增量器的runningTotal指的是不同的。
【问题讨论】:
-
捕获的值被放入堆上的引用计数框,然后存储在函数的上下文对象中(尽管作为优化,在某些情况下可以堆栈提升) - 比较stackoverflow.com/a/40979548/2976878 &(如果您对细节感兴趣)stackoverflow.com/q/43171341/2976878.
-
FWIW,它帮助我将函数视为类型而不是传统函数。