简体   繁体   English

用特征中的抽象类型解决类型擦除问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM