Почему это предупреждение о стирании с переменными-членами, объявленными как кортеж? - PullRequest
9 голосов
/ 07 марта 2011

Посмотрите на этот класс Scala:

class Example {
  val (x, y): (Int, Int) = (1, 2)
}

Компиляция приводит к предупреждению:

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)
                ^

Удаление аннотации явного типа избавляет от этого предупреждения:

class Example {
  val (x, y) = (1, 2)
}

Почему я получаю предупреждение и почему удаление явной аннотации типа избавляет от него?Насколько я вижу, на самом деле ничего не меняется, x и y все еще имеют тип Int без аннотации типа.

Ответы [ 2 ]

13 голосов
/ 07 марта 2011

Вы можете переписать свой пример следующим образом:

class Example {
  val Tuple2(x, y): Tuple2[Int, Int] = Tuple2(1, 2)
}

Это сопоставление с шаблоном на самом деле состоит из 2 совпадений - теперь оно говорит: возьмите правый объект типа Tuple2[Int, Int] и вызовите метод unapply[Int, Int]на сопутствующем объекте Tuple2.Затем unapply[Int, Int] проверит, что объект действительно имеет тип Tuple2, и его результирующее значение будет использовано для привязки значений к переменным x и y.

После этого совпадение с шаблономсодержит : Tuple2[Int, Int], поэтому он пытается выполнить динамическую проверку isInstanceOf[Tuple2[Int, Int]], чтобы определить, имеет ли объект дополнительно тип Tuple2[Int, Int].Однако информация об универсальном типе стирается во время выполнения, поэтому компилятор предупреждает, что он на самом деле не может создать код, который проверяет, что объект создан для параметров типа [Int, Int].

Таким же образом, в следующем сопоставлении с образцом:

val a: AnyRef = (1, 2)
a match {
  case t2: Tuple[Int, Int] => 
}

Вы получите аналогичное предупреждение.

5 голосов
/ 08 марта 2011

Я думаю, что краткий ответ на ваш вопрос:

class Example {
  val (x: Int, y: Int) = (1, 2)
}

, поскольку (Int, Int) является , а не типом, а (x: Int, y: Int) является допустимым выражением шаблона.

...