假设我们想使用类型类来实现 pretty-print :
trait Printer[T] {def print(t: T)}
对于整数的默认实现:
implicit object IntPrinter extends Printer[Int] {
override def print(i : Int): Unit = println(i)
}
我们要打印的具体类型是:
trait Foo {
type K
val k: K
}
class IntFoo extends Foo {
override type K = Int
override val k = 123
}
很酷。现在我想为所有具有可打印 Ks 的 Foos 构建打印机
implicit def fooPrinter[FP <: Foo](implicit ev: Printer[FP#K]): Printer[FP] =
new Printer[FP] {
override def print(f: FP): Unit = {
Predef.print("Foo: ")
ev.print(f.k)
}
}
让我们检查隐式是否已解析:
def main(args: Array[String]) {
implicitly[Printer[Int]]
implicitly[Printer[IntFoo]]
}
scalac 2.11.2 说:
diverging implicit expansion for type Sandbox.Printer[Int]
starting with method fooPrinter in object Sandbox
implicitly[Printer[Int]]
什么?
好的,让我们重写 fooPrinter:
implicit def fooPrinter[KP, FP <: Foo {type K = KP}](implicit ev: Printer[KP]) =
new Printer[FP] {
override def print(f: FP): Unit = {
Predef.print("Foo: ")
ev.print(f.k)
}
}
这在 2.11 中有效,但第一种方法有什么问题? 不幸的是我们在 2.10,第二个解决方案仍然不起作用。它会一直编译,直到我们再添加一台类似的打印机
implicit object StringPrinter extends Printer[String] {
override def print(s : String): Unit = println(s)
}
它神秘地打破了 Printer[IntFoo] 隐式:
could not find implicit value for parameter e:
Sandbox.Printer[Sandbox.IntFoo]
编译器错误?
最佳答案
隐式声明的顺序很重要。在您的源代码中重新排序来自
的原始代码implicit object IntPrinter ...
...
implicit def fooPrinter ...
到
implicit def fooPrinter ...
...
implicit object IntPrinter ...
关于Scala:隐式、子类化和成员类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26152320/