2

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

trait Foo[T: ClassTag]

Error:(11, 35) traits cannot have type parameters with context bounds `: ...' nor view bounds `<% ...'
trait Foo[T: ClassTag]
         ^

如果你定义:

trait Foo[T] {

  implicit def ctg: ClassTag[T] = implicitly[ClassTag[T]]
}

object Bar extends Foo[Int]

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

那么,让 ctg 在自动将子类公开到上下文绑定的特征中定义的最佳方法是什么?

4

1 回答 1

8

没有什么好办法。上下文绑定是隐式参数的简写,并且特征没有参数。也就是说,当你写:

 class Foo[T : ClasTag]

编译器将您的代码脱糖以:

 class Foo[T](implicit ev: ClassTag[T])

这当然是不可能的。如果您必须使用 trait 解决这个问题,您可以创建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]
于 2016-05-17T00:27:18.267 回答