Vogon Jeltz
Vogon Jeltz

Reputation: 1315

Scala pattern matching error in generic function

I have written a generic function to get a value from a HashMap[String, AnyVal]. This method returns a value from the name but also has a functionality to make sure it is of a specific type:

class Context {
  private var variables = HashMap[String, Any] ()

  def getVariable (name: String):Any = variables(name)
  def setVariable (name: String, value: Any) = variables += ((name, value))

  def getVariableOfType[T <: AnyVal] (name:String):T ={
    val v = variables(name)
    v match {
      case T => v.asInstanceOf[T]
      case _ => null.asInstanceOf[T]
    }
  }

}

The function getVariableOfType[T <: AnyVal] will not compile because it says "Cannot resolve symbol T" at the line case T => v.asInstanceOf[T]

Upvotes: 2

Views: 599

Answers (1)

Kolmar
Kolmar

Reputation: 14224

Simply having case x: T => v.asInstanceOf[T] will match any type because of erasure. To really do the type checking you have to make a ClassTag available for T: [T <: AnyVal : ClassTag].

Here is a working definition of getVariableOfType:

import scala.reflect.ClassTag

def getVariableOfType[T <: AnyVal : ClassTag] (name:String):T ={
  val v = variables(name)
  v match {
    case x: T => x
    case _ => null.asInstanceOf[T]
  }
}

The downside is that ClassTag doesn't completely remove the issue of erasure. So requesting for example a Seq[Int], will actually match on every type of sequence (Seq[Double], Seq[String], etc.). In your example T is a subtype of AnyVal, so this won't be an issue.

Upvotes: 6

Related Questions