2016-12-15 158 views
0
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,由于斯卡拉不会做深拷贝,为什么值依然坚持为1,它应该是10 ..我要去的地方错了斯卡拉封闭词法范围

2 )我已经阅读了一些文章,在scala中关闭不深复制对象,他们只是继续引用对象。这究竟意味着什么

回答

1

由于您复制它的方式,您的示例有点难以理解(它看起来像创建单元格时运行的所有代码,但如果这是真的,则会得到无限递归)。 f1和f2返回不同结果的原因是它们指向不同的单元格。你是对的,当你写:

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 = [email protected] 

scala> val b = a 
b: Cell = [email protected] 

我们可以看到a和b包含对同一单元格的引用。

scala> a.x = 10 
a.x: Int = 10 

scala> b.x 
res0: Int = 10 

当我们更新a引用的类时,它也会更新b。

scala> a = new Cell(7) 
a: Cell = [email protected] 

scala> b 
res1: Cell = [email protected] 

scala> a.x 
res2: Int = 7 

scala> b.x 
res3: Int = 10 

当我们分配变量a到新的小区,它具有不同的参考位置(它是细胞的不同实例)。 b仍然有相同的参考(为什么不呢?)。