Универсальный массив Scala - PullRequest
3 голосов
/ 15 октября 2010

Я пытаюсь объявить метод в абстрактном классе, который получает массив универсального типа T. Таким образом:

abstract class Circle[-T] extends Shape[T] {
   def draw(points: Array[T]): Unit
}

Проблема, которую я получаю, состоит в том, что компилятор Scala жалуется на:

Контравариантный тип T встречается в инвариантной позиции в массиве [T] значений значений

Итак, есть ли способ решить эту проблему, кроме следующего?

def draw[U <: T](points: Array[U]): Unit

Как примечание, мне также нужно расширить этот класс в Java.

Ответы [ 2 ]

4 голосов
/ 15 октября 2010

Массив Scala отображается непосредственно на массивы Java и является инвариантом ([T] вместо [+T])

Массив - хитрый зверь.Речь идет об единственной вещи, которая претворяется в жизнь в JVM, и общеизвестно, что дисперсия массива преднамеренно нарушена, чтобы могли быть реализованы такие методы, как Arrays.sort ()."истинная" коллекция Java здесь.

Чтобы ответить на более общий вопрос: Да, если вы хотите использовать параметризованный инвариантный тип в методе противоположного варианта класса, вы должны указать верхнюю границу вподпись для этого метода

3 голосов
/ 15 октября 2010

Относится к этому вопросу.Вы можете пропустить проверку на дисперсию

scala> import scala.annotation.unchecked.uncheckedVariance
import scala.annotation.unchecked.uncheckedVariance

scala> abstract class Circle[-T] extends Shape[T @uncheckedVariance] {
     |    def draw(points: Array[_<:T]): Unit
     | }
defined class Circle

или использовать границы вида

scala> abstract class Circle[T<%T] extends Shape[T]{
     | def draw(points: Array[_<:T]): Unit
     | }
defined class Circle
...