Тип добычи в Скала - PullRequest
       24

Тип добычи в Скала

5 голосов
/ 09 мая 2011

Я довольно новичок в Scala и продвинутых языках программирования.Я пытаюсь решить следующую проблему.

Я получил:

val s: Seq[SomeMutableType[_]]

Я предполагаю, что все элементы в последовательности одного типа (но не знаю, какой из них на данный момент).

Как мне позвонить:

def proc[T](v0: SomeMutableType[T], v1: SomeMutableType[T]) { /* ... */ }

с чем-то вроде

proc(s(0), s(1))

Компилятор жалуется:

  • несоответствие типов;Найдено: SomeMutableType [_ $ 351], где требуется тип _ $ 351: SomeMutableType [Любой] Примечание: _ $ 351 <: Любой, но класс SomeMutableType инвариантен в типе T. Вместо этого вы можете определить T как + T.(SLS 4.5) </li>

Я думал об этой ковариантной вещи, но я не верю, что это имеет смысл в моем случае.Я просто хочу, чтобы компилятор поверил мне, когда я скажу, что s (0) и s (1) одного типа!Я обычно делаю это с помощью некоторого приведения, но я не могу привести к SomeMutableType [T] здесь, так как T неизвестно из-за стирания.Конечно, я не могу изменить определение proc.

Ответы [ 2 ]

4 голосов
/ 09 мая 2011

Проблема в том, что вы действительно не можете дать такую ​​гарантию.Например:

scala> import scala.collection.mutable.Buffer
import scala.collection.mutable.Buffer

scala> val s: Seq[Buffer[_]] = Seq(Buffer(1), Buffer("a"))
s: Seq[scala.collection.mutable.Buffer[_]] = List(ArrayBuffer(1), ArrayBuffer(a))

Видите?Вы не знаете, что s(0) и s(1) относятся к одному и тому же типу, поскольку они могут не относиться к одному и тому же типу.

На этом этапе вам следует задать вопросо том, чего вы хотите достичь, вместо того, чтобы спрашивать, как решить проблему в , как вы хотите это сделать.Они так и не сработают.Отойдите назад, подумайте, какую проблему вы пытались решить с помощью этого подхода, и спросите, как решить эту проблему.

Например, вы скажете:

Я предполагаю, что все элементы впоследовательность того же типа (но не знаю, какой из них на данный момент).

Возможно, вы захотите параметризовать класс или метод и использовать его параметр типа, когдаобъявив s.Или, может быть, вообще не иметь s.

1 голос
/ 09 мая 2011

Я новичок в Scala, но, насколько я понимаю, ваша проблема заключается в использовании параметра подстановочного типа при объявлении s:

val s: Seq[SomeMutableType[_]]

Насколько я понимаю, стирание типа всегда будетпроизойдет, и вам действительно нужен параметризованный тип, связанный с инициализацией s.

Например:

scala> class Erased(val s: List[_])
defined class Erased

scala> new Erased(List(1,2,3)).s.head
res21: Any = 1

Если вместо этого вы используете

scala> class Kept[T](val s: List[T])
defined class Kept

scala> new Kept(List(1,2,3)).s.head
res22: Int = 1

Тогдасодержимое s сохраняет информацию о своем типе, поскольку оно связано с T. То есть именно так вы сообщаете компилятору, что s (0) и s (1) имеют одинаковый тип).

...