用于定义特征中绑定的scala上下文的简写

时间:2016-05-17 00:02:30

标签: scala type-erasure context-bound

在scala抽象类中,如果要定义上下文绑定,可以简单地使用,例如参数中的[T:ClassTag],但这在特性中是不可能的:

{{1}}

如果你定义:

{{1}}

然后任何在Bar中读取ctg的尝试都会触发StackOverflowError,因为隐式参数变为尾递归。

那么允许在自动将子类暴露给上下文绑定的特征中定义ctg的最佳方法是什么?

1 个答案:

答案 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]