[英]Solving type erasure problems with an abstract type in a trait
I have a situation like this: 我有这样的情况:
import scala.reflect._
trait SomeTrait {
type T
implicit def tag: ClassTag[T]
def func2(x: Any) = x match {
case x: T => "foo"
case _ => "bar"
}
}
case class SomeCaseClass()
class SomeClass extends SomeTrait {
type T = SomeCaseClass
implicit def tag = scala.reflect.classTag[SomeCaseClass]
val x = SomeCaseClass()
def func1() = func2(x)
}
object Main extends App {
val someClass = new SomeClass()
someClass.func1()
}
However, the someClass.func1()
call yields, 但是,
someClass.func1()
调用产生,
java.lang.StackOverflowError
at SomeClass.tag(...)
at SomeClass.tag(...)
at SomeClass.tag(...)
//etc.
as if it's recursively calling itself. 好像它是递归地调用自己。 If I remove the ClassTag, then I have the type erasure warning, which I need to fix.
如果删除了ClassTag,则会收到类型擦除警告,需要修复。 Additionally, I need
SomeTrait
to remain a trait, thus [T : ClassTag]
as a type parameter to is not an option. 另外,我需要
SomeTrait
来保持特征,因此[T : ClassTag]
作为类型参数不是一种选择。 Does anyone know how I can avoid the type erasure warning with an abstract type in a trait? 有谁知道我可以避免在特征中使用抽象类型来避免类型删除警告?
See reflect api : 请参阅体现api :
def classTag[T](implicit ctag: ClassTag[T]): ClassTag[T]
When you call: 你打电话时:
implicit def tag = scala.reflect.classTag[SomeCaseClass]
your execution is: 您的执行是:
implicit def tag = scala.reflect.classTag[SomeCaseClass](tag)
and you receive never ending loop. 而且您会收到永无止境的循环。
Try (in object SomeCase implicit is not visible): 尝试(在对象SomeCase隐式对象中不可见):
object SomeCase {
val tagSomeCaseClass = scala.reflect.classTag[SomeCaseClass]
}
class SomeClass extends SomeTrait {
type T = SomeCaseClass
implicit def tag = SomeCase.tagSomeCaseClass
val x = SomeCaseClass()
def func1() = func2(x)
}
And I checked - it works for me: scala> val someClass = new SomeClass() someClass: SomeClass = SomeClass@371a67ec 我检查了一下-它对我有用:scala> val someClass = new SomeClass()someClass:SomeClass = SomeClass @ 371a67ec
scala> someClass.func1()
res0: String = foo
scala> someClass.func2(4)
res1: String = bar
scala> someClass.func2("String")
res2: String = bar
scala> someClass.func2(SomeCaseClass())
res3: String = foo
I do not know how to suppress warning... 我不知道该如何抑制警告...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.