我有这样的情况:
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()
}
但是,someClass.func1()
调用会产生
java.lang.StackOverflowError
at SomeClass.tag(...)
at SomeClass.tag(...)
at SomeClass.tag(...)
//etc.
好像它递归地调用自己一样。如果我删除ClassTag,那么我有类型擦除警告,我需要修复它。另外,我需要SomeTrait
保持特征,因此[T : ClassTag]
作为类型参数不是一个选项。有谁知道如何在特征中使用抽象类型来避免类型擦除警告?
答案 0 :(得分:3)
请参阅reflect api:
def classTag[T](implicit ctag: ClassTag[T]): ClassTag[T]
致电时:
implicit def tag = scala.reflect.classTag[SomeCaseClass]
你的执行是:
implicit def tag = scala.reflect.classTag[SomeCaseClass](tag)
你会收到永无止境的循环。
尝试(在对象中,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)
}
我检查过 - 它对我有用: 阶> 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
我不知道如何压制警告......