Вот пример, демонстрирующий, как использовать ваши выводы:
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 ищет импликиты?