Shorthand 用于定义特征中绑定的 Scala 上下文
Shorthand for defining scala context bound in trait
在 scala abstract class 中,如果你想定义一个上下文绑定,你可以简单地使用,例如[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 的尝试都会触发 WhosebugError,因为隐式参数变为尾递归。
那么,允许在自动将子classes 暴露给上下文绑定的特征中定义 ctg 的最佳方法是什么?
没有好的方法。上下文绑定是隐式参数的简写,特征没有参数。也就是说,当你写:
class Foo[T : ClasTag]
编译器将您的代码脱糖为:
class Foo[T](implicit ev: ClassTag[T])
这当然不可能有特质。如果你 必须 解决这个问题,你可以使 ClassTag
抽象,并强制 class 扩展它来实现它:
trait Foo[T] {
implicit def ctg: ClassTag[T]
}
object Bar extends Foo[Int] {
implicit val ctg = classTag[Int]
}
这看起来略微更好,中间有一个class,这样你就不需要在定义[=16时指定两次Int
=]:
trait Foo[T] {
implicit def ctg: ClassTag[T]
}
class FooImpl[T](implicit val ctg: ClassTag[T]) extends Foo[T]
object Bar extends FooImpl[Int]
在 scala abstract class 中,如果你想定义一个上下文绑定,你可以简单地使用,例如[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 的尝试都会触发 WhosebugError,因为隐式参数变为尾递归。
那么,允许在自动将子classes 暴露给上下文绑定的特征中定义 ctg 的最佳方法是什么?
没有好的方法。上下文绑定是隐式参数的简写,特征没有参数。也就是说,当你写:
class Foo[T : ClasTag]
编译器将您的代码脱糖为:
class Foo[T](implicit ev: ClassTag[T])
这当然不可能有特质。如果你 必须 解决这个问题,你可以使 ClassTag
抽象,并强制 class 扩展它来实现它:
trait Foo[T] {
implicit def ctg: ClassTag[T]
}
object Bar extends Foo[Int] {
implicit val ctg = classTag[Int]
}
这看起来略微更好,中间有一个class,这样你就不需要在定义[=16时指定两次Int
=]:
trait Foo[T] {
implicit def ctg: ClassTag[T]
}
class FooImpl[T](implicit val ctg: ClassTag[T]) extends Foo[T]
object Bar extends FooImpl[Int]