2010-04-21 14 views
8

podczas eksperymentowania z niektórych rzeczy na REPL, mam do punktu gdzie ja potrzebowałem czegoś takiego:Prosta składnia Scala - próba zdefiniowania operatora "==" - czego mi brakuje?

 
scala> class A(x:Int) { println(x); def ==(a:A) : Boolean = { this.x == a.x; } } 

Wystarczy prosty klasy z „==” operatora.

Dlaczego to nie działa?

Oto wynik:

 
:10: error: type mismatch; 
found : A 
required: ?{val x: ?} 
Note that implicit conversions are not applicable because they are ambiguous: 
both method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A] 
and method any2Ensuring in object Predef of type [A](x: A)Ensuring[A] 
are possible conversion functions from A to ?{val x: ?} 
     class A(x:Int) { println(x); def ==(a:A) : Boolean = { this.x == a.x; } } 
                     ^

To scala 2.8 RC1.

Dzięki

Odpowiedz

14

Musisz zdefiniować funkcję equals(other:Any):Boolean, następnie Scala daje == za darmo, zdefiniowana jako

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

patrz rozdział 28 (Object równości) programowania w Scali więcej na temat napisz funkcję equals, tak aby była to naprawdę relacja równoważności.

Ponadto parametr x przekazany do klasy nie jest zapisywany jako pole. Musisz go zmienić na class A(val x:Int) ..., a następnie będzie miał akcesor, którego możesz użyć, aby uzyskać dostęp do operatora a.x w operatorze equals.

+2

Przypuszczam, że dokładniej jest powiedzieć, że nie jest * dostępny * jako pole, tzn. Nie generuje metod dostępu, chyba że deklarujesz go jako "val", gdy go przekażesz. –

+0

Mm hmm. Alex może chcieć dodać "val" z innych powodów, ale ktoś mógłby odczytać twoją odpowiedź jako sugerującą, że jest potrzebna, aby uzyskać dostęp do 'x' w ciele' równa się'. –

+0

Edytowałem swoją odpowiedź, aby wyjaśnić, że potrzebujesz 'val', aby uzyskać dostęp do' a.x' w ciele 'równa się'. –

7

Komunikat o błędzie jest nieco mylący z powodu zbiegu z jakimś kodem w Predef. Ale tak naprawdę chodzi tutaj o to, że próbujesz wywołać metodę x na twojej klasie A, ale nie zdefiniowano żadnej metody o tej nazwie.

Spróbuj:

class A(val x: Int) { println(x); def ==(a: A): Boolean = { this.x == a.x } } 

zamiast. Ta składnia powoduje, że x jest członkiem A, wraz ze zwykłymi metodami dostępowymi.

Jak wspomniał Ken Bloom, dobrym pomysłem jest zastąpienie equals zamiast ==.

Powiązane problemy