我有这段代码,我想知道变量
x
的值是否在定义时被函数捕获,或者函数是否捕获对变量本身的引用(或者还有其他东西) )?
如果
x
是 val
,所有内容的处理方式是否会有所不同?
// Kotlin
var x = 1
fun f(y: Int) = x + y // Function adds 1 to a given Int
x = 2
val y = 3
val z = f(x + y) // Calls f with argument of 5
// z now maps to 7
// Swift
var x = 1
func f(_ y: Int) -> Int {return x + y} // Function adds 1 to a given Int
x = 2
let y = 3
let z = f(x + y) // Calls f with argument of 5
// z now maps to 7
因此,每当我们调用函数
f
时,我们都会在定义函数的环境中评估其主体{ x + y }
。当我们定义这个函数时,我们有一个环境x == 1
。
所以函数
f
总是在它的参数上加 1,无论它在哪里被调用。这就是规则。 (这条规则是针对let
/ val
,而不是我认为的var
?)
我的问题是关于与
var
相关的函数闭包。
请给我对此的详细解释(按照作用域链在内存中定位变量),谢谢。
在 Kotlin 和 Swift 中,使用 var 意味着闭包捕获变量本身的 reference,而 val / let 是不可变的,在闭包创建时捕获变量的 value。
按照您给出的示例,如果您使用 val 代替,您将得到以下结果:
val x = 1
val g = { x + 3 } // Closure g captures the value 1
x = 2
val z = g() // z will be 4 (1 + 3)