假设我有
class A(val x:Int)
class B(val x:Int)
class C(val x:Int)
和
implicit def aPrinter = new PrettyPrinter[A] {def printed(a:A) = s"A(${a.x})"}
implicit def bPrinter = new PrettyPrinter[B] {def printed(b:B) = s"B(${b.x})"}
implicit def cPrinter = new PrettyPrinter[C] {def printed(c:C) = s"C(${c.x})"}
(旁注:也可以帮助找出如何避免这种锅炉板over here)
,其中
trait PrettyPrinter[T]{
def printed(x:T) : String
}
object PrettyPrinter{
def pretty[T](x:T)(implicit pretty:PrettyPrinter[T]) = pretty printed x
implicit def prettyList[T:ClassTag](implicit p :PrettyPrinter[T]) = new PrettyPrinter[List[T]] {
def printed(x:List[T]) = x.map(p.printed).mkString("List(",", ",")")
}
}
如果我想打印我指定类型的集合,例如
val as = new A(1) :: new A(7) :: new A(3) :: Nil
println(pretty(as))
事情很好。
但是,我没有运气
val list = new A(1) :: new B(2) :: new C(9) :: new A(7) :: new A(3) :: Nil
因为它们只被视为Object
的实例,而我没有PrettyPrinter[Object]
。
有什么方法可以克服这个限制吗?
即。我想要的是这样的东西(不会编译,因为试图找到PrettyPrinter[T]
):
implicit def prettyList[T:ClassTag] = new PrettyPrinter[List[T]] {
def printed(x:List[T]) = x.map(pretty).mkString("List(",", ",")")
}
会尝试为每个元素的实际类型找到隐式PrettyPrinter
(第一个元素为PrettyPrinter[A]
,第二个元素为PrettyPrinter[B]
,... )。