2016-09-29 28 views
0

我有这样的事情:在功能转型上输入参数的副作用

object MyObject { 
    var element1 /**/ 
    var element2 /**/ 
    var myOtherObject: OtherObject = new OtherObject 
} 

object MyOtherObject { 
    var something1 /**/ 
    var something2 /**/ 
    var myList: List[T] = List() 
} 

def myUpdateFunction(iMyObject: MyObject) : SomeObject = { 
    var myCopiedObject = iMyObject 

    myCopiedObject.myList.dropRight 
    /*checkpoint*/ 

    val myAwesomeOtherObject = new MyOtherObject 
    /*perform multiple tasks to update myAwesomeOtherObject members*/ 

    myAwesomeOtherObject 
} 

当我检查的“关卡”注释行,我看到我的myCopiedObject.myList已经成功地进行了改造,但myUpdateFunction执行我的iMyObject也有,即。 iMyObject.myList被一个截断。

我不明白这是怎么发生的。

任何线索,任何人?

顺便说一句,我使用spark

+1

iMyObject创建副本是为myObject的实例的引用。你赋值给myCopiedObject纯粹只是基于引用。您需要制作一个iMyObject的新副本。 –

+0

在Scala中使用'var'被认为是一种不好的习惯,所以如果可以的话,应该避免它。 –

回答

2

这是因为你只是分配相同的对象到另一个引用。 myCopiedObject不是您的对象的副本。您应该编写一个方法,该方法将使用与iMyObject保持相同的值创建MyObject的新实例。

2
var myCopiedObject = iMyObject 

上述代码不会创建对象的副本。你基本上是指相同的对象,但使用不同的参考。

使用case class和使用copy方法与要求的变化

case class Something(list: List[Int]) 

val sthing = Something(List(1, 2)) 
val copy = sthing.copy(list = sthing.list.take(1)) //creating changed copy using copy method