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