5

私は大きなオブジェクトを持っています:

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

値を再評価せずにこのオブジェクトをコピーしたいと思います。出来ますか?現在、私はこのアプローチを使用しています:

val newBigObject = oldBigObject.copy(str = newStr)

ログ/デバッガーからわかるように、「someVal」と「someVal2」が再評価されます。それを避けることは可能ですか?私の BigObject は非常に大きく、値の再評価には時間がかかるため、パフォーマンスは私にとって非常に重要です。

回答ありがとうございます。

4

1 に答える 1

8

方法は次のとおりです。

コンストラクターにも渡されるフィールドsomeValsomeVal2フィールドを作成し、コンパニオン オブジェクトでこれらのフィールドの初期化ロジックを引き出します。

あなたの場合:

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)
  }

}

これで、内部フィールドを再評価せずにコピーできます。

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

または、コンパニオン オブジェクトが気に入らない場合は、2 つのコンストラクターを作成できます。プライマリーにはすべてのフィールド (非表示のフィールドも含む) が含まれ、非公開になります。公開されているものには、次の 2 つの可視パラメーターのみがあります。

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)
  }

}

使用法:

val bigObj = new BigObject("hello", 42)
val anotherBigObj = bigObj.copy(newStr = "anotherStr")
于 2013-03-22T10:43:46.527 に答える