[英]Shorthand for defining scala context bound in trait
In scala abstract class, if you want to define a context bound, you can simply use, eg [T: ClassTag] in parameter, however this is not possible in trait: 在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]
^
if you define: 如果您定义:
trait Foo[T] {
implicit def ctg: ClassTag[T] = implicitly[ClassTag[T]]
}
object Bar extends Foo[Int]
then any attempt to read ctg inside Bar will trigger a StackOverflowError, as the implicit parameter becomes tail-recursive. 那么任何在Bar内部读取ctg的尝试都会触发StackOverflowError,因为隐式参数变为尾递归。
So what's the best way to allow ctg to be defined in a trait that automatically expose subclasses to context bound? 那么,允许在自动将子类暴露于上下文绑定的特征中定义ctg的最佳方法是什么?
There isn't a nice way. 没有一个好方法。 A context bound is short-hand for an implicit parameter, and traits do not have parameters.
上下文绑定是隐式参数的简写,而特征没有参数。 That is, when you write:
也就是说,当您编写:
class Foo[T : ClasTag]
The compiler de-sugars your code to: 编译器将您的代码分解为以下内容:
class Foo[T](implicit ev: ClassTag[T])
This is of course not possible with a trait. 当然,这是不可能的。 If you must work around this with a trait, you can make the
ClassTag
abstract, and force the class that extends it to implement it: 如果必须使用特质解决此问题,则可以将
ClassTag
抽象化,并强制对其进行扩展的类来实现它:
trait Foo[T] {
implicit def ctg: ClassTag[T]
}
object Bar extends Foo[Int] {
implicit val ctg = classTag[Int]
}
This looks slightly better with a class in the middle, so that you don't need to specify Int
twice when defining Bar
: 这略好看起来在中间的一类,这样你就不需要指定
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]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.