在Scala中键入提取

sca*_*1sk 5 types scala covariance

我是Scala和高级编程语言的新手.我尝试解决以下问题.

我有:

val s: Seq[SomeMutableType[_]]
Run Code Online (Sandbox Code Playgroud)

我假设序列中的所有元素都是相同的类型(但此时不知道哪一个).

我怎么称呼:

def proc[T](v0: SomeMutableType[T], v1: SomeMutableType[T]) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

喜欢的东西

proc(s(0), s(1))
Run Code Online (Sandbox Code Playgroud)

编译器抱怨:

  • 类型不匹配; found:SomeMutableType [_ $ 351]其中type _ $ 351 required:SomeMutableType [Any]注意:_ $ 351 <:Any,但类SomeMutableType在类型T中是不变的.您可能希望将T定义为+ T.(SLS 4.5)

我想到了那个协变的东西,但我不相信它在我的情况下是有道理的.当我说s(0)和s(1)属于同一类型时,我只想让编译器相信我!我通常通过一些转换来做这个,但我不能在这里强制转换为SomeMutableType [T],因为T由于擦除而未知.当然,我无法改变proc的定义.

Dav*_*lin 1

我是 Scala 的新手,但据我所知,您的问题是在声明 s 时使用通配符类型参数:

val s: Seq[SomeMutableType[_]]
Run Code Online (Sandbox Code Playgroud)

据我了解,类型擦除总是会发生,而您真正想要的是绑定到 s 初始化位置的参数化类型。

例如:

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

scala> new Erased(List(1,2,3)).s.head
res21: Any = 1
Run Code Online (Sandbox Code Playgroud)

如果你使用

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

scala> new Kept(List(1,2,3)).s.head
res22: Int = 1
Run Code Online (Sandbox Code Playgroud)

然后 s 的内容保留其类型信息,因为它绑定到 T。即,这正是您告诉编译器“s(0) 和 s(1) 属于同一类型”的方式。