Почему не работает этот почти идентичный класс значений?
Как и было обещано на http://docs.scala-lang.org/overviews/core/value-classes.html, это работает:
class Wrapper(val self: Int) extends AnyVal {
def toHexString: String = java.lang.Integer.toHexString(self)
}
println(12.toHexString)
Но это не компилируется:
class Wrapper(val self: Int) extends AnyVal {
def whyNot: String = java.lang.Integer.toHexString(self)
}
println(12.whyNot)
Почему бы и нет? Единственное, что я изменил, это название метода!
Вот сообщение об ошибке:
error: value whyNot is not a member of Int
println(12.whyNot)
^
Да, я дважды проверил на счтупить символы Юникода внутри whyNot
,
2 ответа
Predef.scala определяет неявное преобразование из Int в RichInt:
@inline implicit def intWrapper(x: Int) = new runtime.RichInt(x)
Когда вы звоните println(12.toHexString)
он не смотрит на ваш Wrapper, он выполняет неявное преобразование в RichInt и использует определенный там метод.
Если вы хотите ваше собственное неявное преобразование, вам нужно определить его, используя implicit
ключевое слово:
implicit class Wrapper(val self: Int) extends AnyVal {
def whyNot: String = java.lang.Integer.toHexString(self)
}
println(12.whyNot) // prints "c"
Я не уверен, почему вы думаете, что это должно скомпилироваться.
Целые числа не имеют whyNot
метод. Wrapper
с whyNot
метод, но 12
является Int
не Wrapper
,
Вам нужно позвонить whyNot
на Wrapper
объект:
new Wrapper(12).whyNot
// => "c"