Home > database >  Scala how to fix type erasure warning even though I added ClassTag
Scala how to fix type erasure warning even though I added ClassTag

Time:12-05

I am wondering how to fix the type erasure warning even though I added ClassTag? is there an easy fix without adding an additional library like TypeTag?

import scala.reflect.ClassTag

class Node
class C_PHYLUM[T]
class I_PHYLUM[T](name: String)
trait C_SEQUENCE[T1,T2]
class T_SEQUENCE[T]

class M_SEQUENCE[T_ElemType <: Node : ClassTag](name : String, t_ElemType:C_PHYLUM[T_ElemType])
  extends I_PHYLUM[T_SEQUENCE[T_ElemType]](name)
    with C_SEQUENCE[T_SEQUENCE[T_ElemType],T_ElemType]
{
  type T_Result = T_SEQUENCE[T_ElemType];
  def u__op_AC(x:Any) : Option[(T_Result,Seq[T_ElemType])] = x match {
    case x : T_Result => Some((x,toList(x)));
    case _ => None
  };

  def toList[T](x: T): Seq[T_ElemType] = Seq(x.asInstanceOf[T_ElemType])
}

Warning:

warning: abstract type T_ElemType in type pattern T_SEQUENCE[T_ElemType] (the underlying of M_SEQUENCE.this.T_Result) is unchecked since it is eliminated by erasure
    case x : T_Result => Some((x,toList(x)));

Re-producable example

CodePudding user response:

Type erasure is a consequence of how generics are implemented on the JVM. It means that a runtime, you won't be able to tell the difference between e.g. a List[Int] and a List[String]; all the runtime knows is that you have a List. The knowledge of whether you're expecting [Int] or [String] is compile-time only.

In your case, you have T_SEQUENCE[T_ElemType] - so given some object of type Any, you can use isInstanceOf to check if you have an instance of some T_SEQUENCE, but there's no knowledge of what the type parameter on it is.

You could make an assumption that your method will never receive a T_SEQUENCE with the wrong type parameter, and use that to do

case x : T_SEQUENCE[_] => Some((x.asInstanceOf[T_Result],toList(x.asInstanceOf[T_Result])))

Or, assuming your T_SEQUENCE class has some kind of .map method that lets you transform the value inside, you could do something that delegates to the ClassTag that you brought in, e.g.

// I'll assume a method like this exists:
def transformTSeq[A, B](tSeq: T_SEQUENCE[A], f: A => Option[B]): Option[T_SEQUENCE[B]]

// inside your match
case x: T_SEQUENCE[_] =>
  transformTSeq(x, value => {
    implicitly[ClassTag[T_ElemType]].unapply(value)
  })
case _ => 
  None

P.S. get rid of those semicolons

  • Related