8

私は自分のコードでcaseクラスを多用し、caseクラスの基礎となる等価定義に応答して正しく動作しました。次に、ケースクラスに別のフィールドメンバーを追加する必要があることがわかりました。

  1. したがってvar、caseクラスにフィールドメンバーを追加すると、caseクラスの等価属性が台無しになりますか?
  2. 1がyesの場合、varフィールド値を1回変更しただけで、その後、ケースクラスがコレクションに入る前、または同等性の比較を行う前に、再割り当てが行われない場合はどうなりますか?それでも同等性の動作が台無しになりますか?
4

2 に答える 2

13

ケースクラスの同等性は、そのプライマリコンストラクター属性にのみ基づいていますvarvalそうです、ケースクラスコンストラクター引数が持つ暗黙のオーバーライドvarを明示的に指定することでそれらを作成できます)。aの本体にプロパティを追加しても影響はありません。コンパイラーが生成したメソッド。varvalcase class equals(other: Any)

目撃者:

package rrs.scribble

object  CCVarEq
{
  case class CC1(i: Int, j: Float, var k: Double)

  case class CC2(i: Int, j: Float, var k: Double) {
    var l = math.Pi
  }

  def show {
    val cc11 = CC1(1, 2.0f, 3.0)
    val cc12 = CC1(1, 2.0f, 3.0)

    val cc21 = CC2(1, 2.0f, 3.0); cc21.l = math.E
    val cc22 = CC2(1, 2.0f, 3.0)

    printf("cc11 == cc12: %s%n", cc11 == cc12); cc12.k = math.Pi * math.E
    printf("cc11 == cc12: %s%n", cc11 == cc12)

    printf("cc21 == cc22: %s%n", cc21 == cc22)
  }
}

REPLでは:

scala> import rrs.scribble.CCVarEq._
import rrs.scribble.CCVarEq._

scala> show
cc11 == cc12: true
cc11 == cc12: false
cc21 == cc22: true

そして、並行性に関するすべてのジェイミーのポイントも有効です。

于 2013-01-16T02:10:34.967 に答える
3

それほど単純ではありません。あるスレッドでケースクラスvarを更新すると、別のスレッドが同等性チェックを実行しています。変数が揮発性でない限り、等価性チェックが実行される前に、変数への変更が他のスレッドに伝播されない可能性があります。したがって、競合状態になる可能性があります。これが1回だけ発生するか、何度も発生するかは関係ありません。

その時点までに未定義の値は変更されますか?もしそうなら、怠惰なvalを使用してください。同期の問題があり、高性能コードの速度が低下する可能性がありますが、それ以外の場合はユースケースに適合します。

于 2013-01-16T00:03:36.630 に答える