Determining type of value in Map using Pattern Matching


#1

Consider the following two functions and a map declared below.

def getValueFromMap(key:String, dataMap: collection.Map[String, Any]): Option[Int] =
dataMap(key) match {case value:Int => Some(value) }

def getValueFromMap1[T](key:String, dataMap: collection.Map[String, Any]): Option[T] =
dataMap(key) match {case (value:T) => Some(value)}

val map1:collection.Map[String, Any] = Map(“one”->“ONE”, “map” -> Map(“one”->“Hello”, “two” -> 2, “three” -> Map(“a”->“b”)))

Given the above two functions and map1, calling getValueFromMap as below gives "no match error "
val map1Res = getValueFromMap(“one”, map1)

whereas
calling getValueFromMap1 as given below gives the result “Some(ONE)”

val map1Res = getValueFromMap1[Int](“one”, map1)

I am thinking that calling getValueFromMap1 should also give the “no match error”
Please clarify.


#2

Compiling getValueFromMap1 should give compilation warning. Type erasure when compiling to Java bytecode means that generic parameters are erased to java.lang.Object (unless they have upper bounds, in which case they are erased to upper bounds). When compiler sees case (value: T) but there is no class Manifest nor ClassTag in scope for type T then it is equivalent to case (value: Any). You can add automatically generated ClassTag by introducing type bounds, i.e. changing [T] to [T: ClassTag].

Checking if some value has type equal to generic parameter is generally an unpopular thing (except perhaps in C#, but I don’t care about that language) and also rather unfavourable as it moves type checking from compile time to runtime. Instead of doing the compiler’s job manually, use Scala’s powerful type system.


#3

Thanks Tarsa. It makse sense. Sometimes we have to maintain the old code as well and forced to do this sort of unpopular things.