2012-03-24 6 views
7

私はScalaのProgrammingを読んでいます。それは言う:Scala:==デフォルトは等しいですか?

あなたは常にクラスAnyから継承されequals方法を、オーバーライドすることにより、新しいタイプのため==の振る舞いを再定義することができます。継承されたequalsは、Javaの場合のように、オーバーライドされない限り有効なオブジェクトIDです。したがって、equals(それとともに、==)はデフォルトでeqと同じですが、定義したクラスのequalsメソッドをオーバーライドすることでその動作を変更できます。 Anyの最終メソッドとして定義されているため、==を直接オーバーライドすることはできません。それは、クラスAnyで次のように定義されていたかのようにScalaは==を扱い、次のとおりです。

final def == (that: Any): Boolean = 
    if (null eq this) (null eq that) else (this equals that) 

しかし、これは、私はそれはのように思えるのScala 2.9.1で見ているものとjibingされていません。

  • ==は、私は(コンパイラからの苦情なしで、何overrideは必要ありません)を直接==をオーバーライドすることができますequals
  • をデフォルトにしていないようです。

だから、どちらかのように私には思える:

  • 私が間違ってそれをやっている - this definition of Rational

    % scala                 
    Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_29). 
    Type in expressions to have them evaluated. 
    Type :help for more information. 
    
    scala> Rational(1) == Rational(1) 
    res0: Boolean = false 
    
    scala> Rational(1) equals Rational(1) 
    res1: Boolean = true 
    
  • または私は日版のアウトを読んでいるを与えます本、物事が変わった。

何が起こっているのですか?

答えて

21

あなたは非常に理解しやすい間違いをしています。総称的な等価(すなわち、override def equals(a: Any))の代わりに型安全な等価(つまり、def equals(r: Rational))を書こうとしています。あなたがoverrideキーワードを必要としないので、代わりにオーバーライドequals --noteの

は - !あなたは型パラメータをオーバーロードすることにより、別の方法を作成しているし、その後、はequalsメソッドをとり1 Rationalと1つを有しますこれには Anyが必要です。 ==と同じこと。 Any -parameterizedメソッドのみをオーバーライドすることはできません。

のJavaと一貫した動作(とScalaのライブラリ)を取得するには、リライトする必要があると思い

override def equals(a: Any) = a match { 
    case r: Rational => numer == r.numer && denom == r.demon 
    case _ => false 
} 
+0

恐ろしいようなものとして等しいです。これは私がJVMの土地に戻るたびに私に噛み付きます。私は遅かれ​​早かれそれを学ぶでしょう。とにかく私は 'a match 'を落とし、' equals'に無名関数を代入できますか?あなたは型シグネチャを正確に一致させなければなりません。 – rampion

+2

@rampion - いいえ、タイプシグネチャを正確に一致させる必要があります。 'equals:Any => Boolean'は関数(すなわち、' Function1 [Any、Boolean] 'クラスのインスタンス)を返すことを意味します。これは概念的にはある意味では同等ですが、まったく同じ方法ではないので動作しません。 –

関連する問題