Scala object cloning (copying) without revaluation

I have a big object:

case class BigObject(val str: String, val number: Int) { val someVal = ... val someVal2 = ... } 

I would like to copy this object without re-evaluating the values. Is it possible? I am now using this approach:

 val newBigObject = oldBigObject.copy(str = newStr) 

As I see from the log / debugger, "someVal" and "someVal2" are overridden. Can this be avoided? Since my BigObject is really big, and reevaluating the cost takes some time, but performance is very important to me.

Thank you for your responses!

+4
source share
1 answer

Here is the way:

Create someVal and someVal2 , which are also passed to the constructor and pull out the initialization logic for those fields in the companion object.

In your case:

 class BigObject private(val str: String, val number: Int, val someVal: SomeType, val someVal2: SomeType) { def copy(newStr: String = str, newNumber: Int = number) = { new BigObject(newStr, newNumber, someVal, someVal2) } } object BigObject { def apply(str: String, number: Int): BigObject = { val someVal = initialize() //your initialization logic here val someVal2 = initialize2() new BigObject(str, number, someVal, someVal2) } } 

Now you can copy without re-zeroing the internal fields:

 val bigObj = BigObject("hello", 42) val anotherBigObj = bigObj.copy(newStr = "anotherStr") 

Alternatively, if you don't like companion objects, you can create two constructors. Primary includes all fields (also not visible) and will be closed. Public will have only two visible parameters:

 class BigObject private(val str: String, val number: Int, val someVal: Any, val someVal2: Any) { def this(str: String, number: Int) = this(str, number, initializeVal, initializeVal2) def copy(newStr: String = str, newNumber: Int = number) = { new BigObject(newStr, newNumber, someVal, someVal2) } } 

Using:

 val bigObj = new BigObject("hello", 42) val anotherBigObj = bigObj.copy(newStr = "anotherStr") 
+6
source

All Articles