2010-04-21 17 views
8

Al experimentar con algunas cosas en el REPL, llegué a un punto en el que necesitaba algo como esto:Sintaxis simple de Scala: tratando de definir el operador "==": ¿qué me falta?

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

Sólo una clase simple con un operador "==".

¿Por qué no funciona ???

Aquí está el resultado:

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

Ésta es Scala 2.8 RC1.

Gracias

Respuesta

14

Usted tiene que definir la función equals(other:Any):Boolean, entonces Scala le da == gratis, definida como

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

Véase el capítulo 28 (Object Igualdad) de Programación en Scala para más información sobre cómo escriba la función equals para que realmente sea una relación de equivalencia.

Además, el parámetro x que pasa a su clase no se almacena como un campo. Debe cambiarlo a class A(val x:Int) ..., y luego tendrá un descriptor de acceso que puede usar para acceder al a.x en el operador equals.

+2

Supongo que es más exacto decir que no es * accessible * como un campo, es decir, no genera métodos de acceso a menos que lo declare como 'val' cuando lo pasa. –

+0

Mm hmm. Alex puede querer agregar 'val' por otras razones, pero alguien podría leer su respuesta como que implica que es necesaria para acceder a' x' en el cuerpo de 'iguales'. –

+0

He editado mi respuesta para aclarar que necesitas 'val' para acceder a' a.x' en el cuerpo de 'equals'. –

7

El mensaje de error es un poco confuso debido a la coincidencia con algún código en Predef. Pero lo que está sucediendo aquí es que estás intentando llamar al método x en tu clase A, pero no se define ningún método con ese nombre.

Probar:

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

lugar. Esta sintaxis hace que x sea miembro de A, con el método de acceso habitual.

Como mencionó Ken Bloom, sin embargo, es una buena idea anular equals en lugar de ==.

Cuestiones relacionadas