2011-04-25 22 views
11
class PasswordCaseClass(val password:String) 
trait PasswordTrait { self:PasswordCaseClass => 
    override def password = "blue" 
} 

val o = new PasswordCaseClass("flowers") with PasswordTrait 

¿Es posible anular PasswordCaseClass 's password con lo dispuesto en PasswordTrait? En este momento, recibo este error:¿Puedo anular un método de clase scala con un método de un rasgo?

e.scala:6: error: overriding value password in class PasswordCase 
Class of type String; 
method password in trait PasswordTrait of type => java.lang.String needs to be a stable, 
immutable value 
val o = new PasswordCaseClass("flowers") with PasswordTrait 
      ^
one error found 

Me gustaría ser capaz de tener algo como esto:

class User(val password:String) { 
} 

trait EncryptedPassword { u:User => 
    def password = SomeCriptographyLibrary.encrypt(u.password) 
} 

val u = new User("random_password") with EncryptedPassword 
println(u.password) // see the encrypted version here 

Respuesta

19

Puede anular def con val, pero no puede hacerlo al revés. Un val implica una garantía, que su valor es estable e inmutable, que un def no lo garantiza.

8

Esto funcionó para mí (con algunas modificaciones):

trait PasswordLike { 
val password: String 
} 

class PasswordCaseClass(val password:String) extends PasswordLike 

trait PasswordTrait extends PasswordLike { 
override val password: String = "blue" 
} 

y luego:

scala> val o = new PasswordCaseClass("flowers") with PasswordTrait 
o: PasswordCaseClass with PasswordTrait = [email protected] 

scala> o.password 
res1: String = blue 
+0

Pero, ¿no debería Scala ser indiferente si estoy usando un campo o un método? – Geo

+3

Bueno, con respecto a la anulación, creo que def puede ser invalidado por val, pero no a la inversa. –

3

Está intentando anular el valor con la definición del método. Simplemente no tiene sentido, tienen una semántica diferente. Los valores que se supone que se calculan una vez por ciclo de vida del objeto (y se almacenan dentro de un atributo de clase final) y los métodos se pueden calcular varias veces. Entonces, lo que estás tratando de hacer es frenar el contrato de la clase de varias maneras.

De todos modos, también hay un error del compilador: la explicación del error no está del todo clara.

+2

El error dice que hay un error en la anulación del * valor * 'contraseña' con un * método *' contraseña': debe usar un "valor estable, inmutable". No puedo ver por qué eso es "totalmente incierto". – gerferra

+0

Creo que la buena explicación debería ser "Colisión del nombre entre las declaraciones val y def". No te lo tomes demasiado en serio, es solo una opinión de un experto en no compiladores. – CheatEx

+0

Creo que ese mensaje es más confuso que el original, personalmente. –

Cuestiones relacionadas