2012-08-09 15 views
7

Scalaの==メソッドは、Javaのequalsメソッドと同じセマンティクスを持っています。しかし、再帰的構造のインスタンスに適用されるときを理解したいと思います。例えば 、表現の束考える:私はBinaryExp、言うobj1obj2の2つのインスタンスを持っているとき、深い(再帰的)平等テストでobj1 == obj2結果を行い、その後再帰的に定義された型のスカラと==メソッド

abstract class Exp 

abstract class BinaryExp(l:Exp, r:Exp) extends Exp 

case class Plus(l:Exp, r:Exp) extends BinaryExp(l,r) 

case class Minus(l:Exp, r:Exp) extends BinaryExp(l,r) 

case class Mult(l:Exp, r:Exp) extends BinaryExp(l,r) 

case class Div(l:Exp, r:Exp) extends BinaryExp(l,r) 

case class Num(v:Int) extends Exp 

を?つまり、obj1 == obj2が保持されている場合、obj1obj2は同じ正確な式ツリーを表しますか?

すべてのクラスで、デフォルトの実装==(どこにでも上書きされません)に依存しています。

答えて

14

これは自分でテストするのは簡単です:

val x = Plus(Num(1), Num(2)) 
val y = Plus(Num(1), Num(2)) 
val z = Plus(Num(1), Num(3)) 

println(x == y) // prints true 
println(x == z) // prints false 

これらは、正しい答えを与えるということは、平等のチェックが部分式の「深い」平等のためにチェックしていることを示しています。

さらに、あなたがdocumentationで見ることができます:Scalaのコンパイラが生成するすべてのケースクラスの

構造的平等を実装するメソッド

「構造平等は」のようなものです等しいですあなたが疑問に思っている深い平等チェック。

最後に、文法上の砂糖について何が起こっているのかを実際に確認したい場合は、を使用するか、scalacを実行するかREPLを起動してください。最初caseに埋もれて、だから、

scala> case class Plus(l:Exp, r:Exp) extends BinaryExp(l,r) 
[[syntax trees at end of typer]]// Scala source: <console> 
... 
case class Plus extends $line2.$read.$iw.$iw.BinaryExp with ScalaObject with Product with Serializable { 
    ... 
    override def equals(x$1: Any): Boolean = Plus.this.eq(x$1.asInstanceOf[java.lang.Object]).||(x$1 match { 
    case (l: $line1.$read.$iw.$iw.Exp, r: $line1.$read.$iw.$iw.Exp)$line3.$read.$iw.$iw.Plus((l$1 @ _), (r$1 @ _)) if l$1.==(l).&&(r$1.==(r)) => x$1.asInstanceOf[$line3.$read.$iw.$iw.Plus].canEqual(Plus.this) 
    case _ => false 
    }); 

あなたはPlus.equalsを確認するためにif l$1.==(l).&&(r$1.==(r))を呼び出していることがわかります:あなたはREPLとそのオプションを使用して、クラスPlusを宣言すると、ここにあなたが(短縮)何を得るのです平等。つまり、ケースクラスの生成された等価メソッドは、サブ式に==を呼び出して、それらの等価性をチェックします。

関連する問題