2010-04-21 12 views
8

Mentre la sperimentazione di alcune cose sul REPL, ho avuto modo di un punto in cui avevo bisogno di qualcosa di simile:Sintassi di Scala semplice - cercando di definire l'operatore "==" - cosa mi manca?

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

Basta una semplice classe con un operatore "==".

Perché non funziona ???

Ecco il risultato:

 
: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; } } 
                     ^

Si tratta di scala 2.8 RC1.

Grazie

risposta

14

È necessario definire la funzione equals(other:Any):Boolean, allora Scala ti dà == gratuitamente, definito come

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

Vedere capitolo 28 (Object uguaglianza) di programmazione a Scala per maggiori informazioni su come scrivere la funzione equals in modo che sia davvero una relazione di equivalenza.

Inoltre, il parametro x passato alla classe non viene memorizzato come campo. È necessario cambiarlo in class A(val x:Int) ... e quindi avrà una funzione di accesso che è possibile utilizzare per accedere a nell'operatore equals.

+2

Suppongo che sia più accurato dire che non è * accessibile * come un campo, cioè non genera metodi di accesso a meno che non lo dichiari come 'val' quando lo passi. –

+0

Mm hmm. Alex potrebbe voler aggiungere 'val' per altri motivi, ma qualcuno potrebbe leggere la tua risposta implicando che è necessario per accedere a' x' nel corpo di 'equals'. –

+0

Ho modificato la mia risposta per chiarire che è necessario 'val' accedere a' a.x' nel corpo di 'equals'. –

7

Il messaggio di errore è un po 'di confusione a causa della coincidenza con un codice in Predef. Ma quello che sta realmente succedendo qui è che stai provando a chiamare il metodo x sulla tua classe A, ma nessun metodo con quel nome è definito.

Prova:

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

invece. Questa sintassi rende x un membro di A, completo del solito metodo di accesso.

Come menzionato da Ken Bloom, tuttavia, è consigliabile ignorare equals anziché ==.

Problemi correlati