Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why this erasure warning with member variables declared as a tuple?

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.

like image 636
Jesper Avatar asked Mar 07 '11 18:03

Jesper


People also ask

What does _* mean in Scala?

: _* 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.

What is type erasure Scala?

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.

How does Scala pattern matching work?

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 “|“.


1 Answers

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.

like image 102
axel22 Avatar answered Oct 03 '22 05:10

axel22