在scala抽象类中,如果要定义上下文绑定,可以简单地使用,例如参数中的[T:ClassTag],但这在特性中是不可能的:
{{1}}
如果你定义:
{{1}}
然后任何在Bar中读取ctg的尝试都会触发StackOverflowError,因为隐式参数变为尾递归。
那么允许在自动将子类暴露给上下文绑定的特征中定义ctg的最佳方法是什么?
答案 0 :(得分:3)
没有一个好方法。上下文绑定是隐式参数的简写,而traits没有参数。也就是说,当你写:
class Foo[T : ClasTag]
编译器将您的代码解压缩为:
class Foo[T](implicit ev: ClassTag[T])
这当然不可能具有特征。如果必须使用特征解决此问题,您可以制作ClassTag
摘要,并强制扩展它的类来实现它:
trait Foo[T] {
implicit def ctg: ClassTag[T]
}
object Bar extends Foo[Int] {
implicit val ctg = classTag[Int]
}
对于中间的类,这看起来略微,因此在定义Int
时您无需指定Bar
两次:
trait Foo[T] {
implicit def ctg: ClassTag[T]
}
class FooImpl[T](implicit val ctg: ClassTag[T]) extends Foo[T]
object Bar extends FooImpl[Int]