Have a look at this Scala class:
class Example {
val (x, y): (Int, Int) = (1, 2)
}
Compiling this results in a warning:
Example.scala:2: warning: non variable type-argument Int in type pattern
(Int, Int) is unchecked since it is eliminated by erasure
val (x, y): (Int, Int) = (1, 2)
^
Removing the explicit type annotation gets rid of this warning:
class Example {
val (x, y) = (1, 2)
}
Why do I get the warning and why does removing the explicit type annotation get rid of it? As far as I can see nothing really changes, x
and y
are still of type Int
without the type annotation.
: _* is a special instance of type ascription which tells the compiler to treat a single argument of a sequence type as a variable argument sequence, i.e. varargs. It is completely valid to create a Queue using Queue.
Type erasure refers to the runtime encoding of parameterized classes in Scala. It is simply performed by Scala compiler in which it removes all the generic type information after compilation. In Scala, generics are erased at runtime, which means that the runtime type of List[Int] and List[Boolean] is actually the same.
Pattern matching allows matching any sort of data with the first match policy. Each case statement returns a value, and the whole match statement is virtually a function that returns a matched value. Multiple values can be tested in a single line by using “|“.
You could rewrite your example to:
class Example {
val Tuple2(x, y): Tuple2[Int, Int] = Tuple2(1, 2)
}
This pattern match actually consists of 2 matches - it now says: take the right hand side object of type Tuple2[Int, Int]
and call the method unapply[Int, Int]
on the Tuple2
companion object. The unapply[Int, Int]
will then verify that the object really has the type Tuple2
, and its result value will be used to bind values to variables x
and y
.
After that, this pattern match contains : Tuple2[Int, Int]
, so it tries to do an isInstanceOf[Tuple2[Int, Int]]
check dynamically to see if the object additionally has the type Tuple2[Int, Int]
. However, generic type information is erased at runtime, so the compiler warns that it cannot actually produce code which verifies that the object is instantiated for type parameters [Int, Int]
.
In the same way, in the following pattern match:
val a: AnyRef = (1, 2)
a match {
case t2: Tuple[Int, Int] =>
}
you would get a similar warning.
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