Проблемы с неявным преобразованием в Scala - PullRequest
6 голосов
/ 02 августа 2011

Возьмите этот код:

  class Register(var value:Int = 0) {
      def getZeroFlag() : Boolean = (value & 0x80) != 0
  }

  object Register {
      implicit def reg2int(r:Register):Int = r.value
      implicit def bool2int(b:Boolean):Int = if (b) 1 else 0
  }

Я хочу использовать это так:

val x = register.getZeroFlag + 10

но меня приветствуют:

type mismatch; found : Boolean required: Int

Что идет? Нужно ли определять неявное взятие функции, которая возвращает bool?

1 Ответ

14 голосов
/ 02 августа 2011

Вот пример, демонстрирующий, как использовать ваши выводы:

object Test {
  val register = new Register(42)
  val x = 1 + register // implicitly calling reg2int from companion object
  val y = register - 1 // same
  // val z = register + 1 // doesn't work because "+" means string concatenation

  // need to bring bool2int implicit into scope before it can be used
  import Register._
  val w = register.getZeroFlag() + 2 // this works now
  val z2 = register + 1 // works because in-scope implicits have higher priority 
}

Две потенциально неочевидные вещи здесь:

  • При поиске неявных преобразований в или из объекта типа Register компилятор будет искать в сопутствующем объекте Register. Вот почему нам не нужно явно вводить reg2int в область для определения x и y. Однако преобразование bool2int действительно должно находиться в области видимости, поскольку оно не определено для сопутствующего объекта Boolean или Int.
  • Метод + уже определен на всех объектах для обозначения конкатенации строк посредством неявного any2stringadd в scala.Predef. Определение val z недопустимо, поскольку неявное объединение строк имеет приоритет над reg2int (обнаруженные в сопутствующих объектах последствия имеют относительно низкий приоритет). Однако определение val z2 работает, потому что мы включили в область действия reg2int, придав ей более высокий приоритет.

Подробнее о том, как компилятор ищет импликации, см. Очень приятное объяснение Даниэля Собрала: Где Scala ищет импликиты?

...