Scala何时真正复制对象?
背景 我有一段代码如下所示:Scala何时真正复制对象?,scala,memory-management,reference,Scala,Memory Management,Reference,背景 我有一段代码如下所示: val big_obj = new BigObj big_obj.recs[5].foo() ... // other code big_obj.recs[7].bar() 问题 我想做这样的事情 val big_obj = new BigObj alias ref = big_obj.recs // looking for something like an alias ref[5].foo() ... // other code ref[7].bar()
val big_obj = new BigObj
big_obj.recs[5].foo()
... // other code
big_obj.recs[7].bar()
问题
我想做这样的事情
val big_obj = new BigObj
alias ref = big_obj.recs // looking for something like an alias
ref[5].foo()
... // other code
ref[7].bar()
因为我害怕复制大对象(来自C++)。但后来我意识到Scala可能很聪明,如果我这么做:
val big_obj = new BigObj
val ref = big_obj.recs // no copies made?
编译器可能足够聪明,不会以任何方式复制,因为它都是只读的
问题
这让我想知道Scala的内存模型
在什么情况下会复制/不复制
我在寻找一个简单的答案或经验法则,当我处理真正的大对象时,无论何时我进行赋值,包括传递参数,我都能记住这个答案或经验法则。就像Java(和python,可能还有很多其他语言)一样,复制从来都不是对象。指定对象或将其作为参数传递时,它仅复制对该对象的引用;实际对象只是位于内存中,并有一个额外的对象指向它。唯一会被复制的是原语(整数、双精度等)
正如您所指出的,这显然适用于不可变对象,但适用于所有对象,即使是可变对象:
scala> val a = collection.mutable.Map(1 -> 2)
a: scala.collection.mutable.Map[Int,Int] = Map(1 -> 2)
scala> val b = a
b: scala.collection.mutable.Map[Int,Int] = Map(1 -> 2)
scala> b += (2 -> 4)
res41: b.type = Map(2 -> 4, 1 -> 2)
scala> a
res42: scala.collection.mutable.Map[Int,Int] = Map(2 -> 4, 1 -> 2)
scala> def addTo(m: collection.mutable.Map[Int,Int]) { m += (3 -> 9) }
addTo: (m: scala.collection.mutable.Map[Int,Int])Unit
scala> addTo(b)
scala> a
res44: scala.collection.mutable.Map[Int,Int] = Map(2 -> 4, 1 -> 2, 3 -> 9)
就像Java(和python,可能还有很多其他语言)一样,拷贝从来都不是由对象构成的。指定对象或将其作为参数传递时,它仅复制对该对象的引用;实际对象只是位于内存中,并有一个额外的对象指向它。唯一会被复制的是原语(整数、双精度等)
正如您所指出的,这显然适用于不可变对象,但适用于所有对象,即使是可变对象:
scala> val a = collection.mutable.Map(1 -> 2)
a: scala.collection.mutable.Map[Int,Int] = Map(1 -> 2)
scala> val b = a
b: scala.collection.mutable.Map[Int,Int] = Map(1 -> 2)
scala> b += (2 -> 4)
res41: b.type = Map(2 -> 4, 1 -> 2)
scala> a
res42: scala.collection.mutable.Map[Int,Int] = Map(2 -> 4, 1 -> 2)
scala> def addTo(m: collection.mutable.Map[Int,Int]) { m += (3 -> 9) }
addTo: (m: scala.collection.mutable.Map[Int,Int])Unit
scala> addTo(b)
scala> a
res44: scala.collection.mutable.Map[Int,Int] = Map(2 -> 4, 1 -> 2, 3 -> 9)
一些早期的OO语言有“浅”复制与“深”复制的概念,并且在某些情况下实际上会复制对象。scala确实有一个“复制”方法,用于复制objects@ElectricCoffee:对象通常没有这样的方法。然而,case类确实如此。一些早期的OO语言有“浅”复制与“深”复制的概念,并且在某些情况下实际上会复制对象。scala确实有一个“复制”方法,用于复制objects@ElectricCoffee:对象通常没有这样的方法。然而,案例类确实如此。