问题
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.
回答1:
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.
回答2:
I think the short answer to your question is:
class Example {
val (x: Int, y: Int) = (1, 2)
}
because (Int, Int)
is not a type, while (x: Int, y: Int)
is a valid pattern expression.
来源:https://stackoverflow.com/questions/5223670/why-this-erasure-warning-with-member-variables-declared-as-a-tuple