I'm learning Scala and trying to write some simple code.
When I tried to write a method like this:
def func(value: Any) {
value match {
case i: Int => println(1)
case vector: Vector[Any] => println(2)
case map: Map[Any, Any] => println(3)
case _ => println(4)
}
}
I got an warn:
[warn]........:31: non-variable type argument Any in type pattern scala.collection.immutable.Map[Any,Any] (the underlying of Map[Any,Any]) is unchecked since it is eliminated by erasure
[warn] case map: Map[Any, Any] => println(3)
[warn] ^
[warn] one warning found
I am wondering why using Map[Any, Any] will get this warn but Vector[Any] will not.
The problem is that a Map[X, Y] is not covariant in its type parameter X (but a Vector[X] is).
What does that mean? Suppose B <: A (read, B is a subtype of A).
Then we have Vector[B] <: Vector[A]. That makes sense: If we retrieve an element x from a Vector[B], it will be a B. That means it is also an A by the subtyping relationship. (A similar argument applies to all other methods.)
Following similar reasoning, Map[X, B] <: Map[X, A] for all X (element retrieval is by key and not index, but essentials remain the same).
However, this doesn't hold for Map's first type parameter. Assume that Map[B, X] <: Map[A, X] for some X.
We could now do the following:
val x: Map[B, X] = ???
x.get(b: B) // makes sense
val y: Map[A, X] = x // must be ok, Map[B, X] <: Map[A, X]
y.get(a: A) // bad! x doesn't know how to "get" with something of type `A`
Therefore, a Map[_, _] is not necessarily a Map[Any, Any]. To fix the error message, use:
case map: Map[_, _] => ...
The reason is that Map is invariant in its first type parameter. This means that not any map is a sub-type of Map[Any,Any].
On the contrary, Vector is covariant in its type parameter, so any Vector is always a sub-type of Vector[Any], which means that the compiler does not need to check if the actual runtime type is Vector[Any] (which it cannot do anyway due to erasure) as even if it is say a Vector[String] it is safe to trat it as a Vector[Any].
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With