Scala 闭包词法作用域
Scala closure Lexical Scope
class Cell(var x: Int)
var c = new Cell(1)
val f1 = () => c.x /* Create a closure that uses c */
def foo(e: Cell) = () => e.x /* foo is a closure generator with its own scope */
// f2 wont do any reference/deep copy
val f2 = foo(c) /* Create another closure that uses c */
val d = c /* Alias c as d */
c = new Cell(10) /* Let c point to a new object */
d.x = d.x + 1 /* Increase d.x (i.e., the former c.x) */
// now c.x refers to 10
println(f1()) /* Prints 10 */
println(f2()) /* Prints 2 */
这里 f2() 打印 2 ,因为 scala 不会进行深度复制,为什么值仍然保留为 1,它应该是 10.. 我哪里错了
2) 我读过 smomehere,scala 中的闭包不深复制对象,它们只是保留对对象的引用。这到底是什么意思
由于您复制它的方式,您的示例有点难以理解(创建 Cell 时看起来所有代码都是 运行,但如果这是真的,您将获得无限递归). f1 和 f2 return 不同结果的原因是它们指向不同的单元格。你是对的,当你写:
val d = c
c 和 d 都包含相同的引用。但是当你写:
c = new Cell(10)
c 现在是对新单元格的引用,d 不会复制该引用。
使用 REPL 更容易看到这一点,它可以打印十六进制引用位置。
scala> class Cell(var x: Int)
defined class Cell
scala> var a = new Cell(5)
a: Cell = Cell@368239c8
scala> val b = a
b: Cell = Cell@368239c8
我们可以看到 a 和 b 包含对同一单元格的引用。
scala> a.x = 10
a.x: Int = 10
scala> b.x
res0: Int = 10
当我们更新 a 引用的 class 时,它也会为 b 更新。
scala> a = new Cell(7)
a: Cell = Cell@5b87ed94
scala> b
res1: Cell = Cell@368239c8
scala> a.x
res2: Int = 7
scala> b.x
res3: Int = 10
当我们将变量 a 分配给新单元格时,它具有不同的引用位置(它是 Cell 的不同实例)。 b 仍然具有相同的引用(为什么不呢?)。
class Cell(var x: Int)
var c = new Cell(1)
val f1 = () => c.x /* Create a closure that uses c */
def foo(e: Cell) = () => e.x /* foo is a closure generator with its own scope */
// f2 wont do any reference/deep copy
val f2 = foo(c) /* Create another closure that uses c */
val d = c /* Alias c as d */
c = new Cell(10) /* Let c point to a new object */
d.x = d.x + 1 /* Increase d.x (i.e., the former c.x) */
// now c.x refers to 10
println(f1()) /* Prints 10 */
println(f2()) /* Prints 2 */
这里 f2() 打印 2 ,因为 scala 不会进行深度复制,为什么值仍然保留为 1,它应该是 10.. 我哪里错了
2) 我读过 smomehere,scala 中的闭包不深复制对象,它们只是保留对对象的引用。这到底是什么意思
由于您复制它的方式,您的示例有点难以理解(创建 Cell 时看起来所有代码都是 运行,但如果这是真的,您将获得无限递归). f1 和 f2 return 不同结果的原因是它们指向不同的单元格。你是对的,当你写:
val d = c
c 和 d 都包含相同的引用。但是当你写:
c = new Cell(10)
c 现在是对新单元格的引用,d 不会复制该引用。
使用 REPL 更容易看到这一点,它可以打印十六进制引用位置。
scala> class Cell(var x: Int)
defined class Cell
scala> var a = new Cell(5)
a: Cell = Cell@368239c8
scala> val b = a
b: Cell = Cell@368239c8
我们可以看到 a 和 b 包含对同一单元格的引用。
scala> a.x = 10
a.x: Int = 10
scala> b.x
res0: Int = 10
当我们更新 a 引用的 class 时,它也会为 b 更新。
scala> a = new Cell(7)
a: Cell = Cell@5b87ed94
scala> b
res1: Cell = Cell@368239c8
scala> a.x
res2: Int = 7
scala> b.x
res3: Int = 10
当我们将变量 a 分配给新单元格时,它具有不同的引用位置(它是 Cell 的不同实例)。 b 仍然具有相同的引用(为什么不呢?)。