Scala неявное преобразование из родительского признака
Следующий код не компилируется:
import scala.language.implicitConversions
trait Base {
class Wrp[+T](val v: T) // wrapper / internal representation
}
trait BooleanOps extends Base {
// implicit conversion
implicit def lift2BooleanOpsCls(x: Boolean): BooleanOpsCls =
new BooleanOpsCls(new Wrp[Boolean](x))
class BooleanOpsCls(wx: Wrp[Boolean]) {
def ||(wy: =>Wrp[Boolean]): Wrp[Boolean] = new Wrp[Boolean](wx.v || wy.v)
}
}
trait MyExample extends BooleanOps {
// test method
def foo(): Wrp[Boolean] = {
val ret: Wrp[Boolean] = false || new Wrp[Boolean](true)
ret
}
}
Вывод:
MyExample.scala:18: error: type mismatch;
found : MyExample.this.Wrp[Boolean]
required: Boolean
val ret: Wrp[Boolean] = false || new Wrp[Boolean](true)
^
Но если I:
1) поместите class Wrp
вне базы
или
2) переместите тело BooleanOps
в MyExample
все компилируется.
Почему исходный пример не работает? Если у вас есть некоторое понимание этого поведения, помощь будет оценена по достоинству. Спасибо.
Ответы
Ответ 1
Одна из проблем - это вызов по имени аргумента в def ||(wy: =>Wrp[Boolean])
если вы переписываете его на def ||(wy: Wrp[Boolean])
, он работает
но я согласен с тем, что это странно, что он работает, если вы перемещаете Wrp или BooleanOpsCls! Предполагаемый или ошибка неявного разрешения
Ответ 2
Исходный пример будет работать, если вы переименуете метод ||
. Компилятор находит метод false.||()
и не пытается искать неявный, который также может работать там.
Ответ 3
Проблема заключается в том, что не существует одного класса с именем Wrp
(игнорируйте T
на мгновение) - Base
не определяет Wrp
, а скорее определяет именованный подкласс каждого конкретного класса, продолжается Base
. Имплициты - тоже красная селедка. Ошибка в том, что раздача является упоминанием MyExample.this.Wrp
- помните, что такого класса нет, даже если MyExample
- val x = new MyExample
будет иметь тип Object with MyExample
.