Почему не работает этот почти идентичный класс значений?

Как и было обещано на 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"
Другие вопросы по тегам