本地分配会影响类型?

use*_*956 6 generics scala

在以下示例中,f3可以采用Iterable [Array [Int]]

  def f3(o:Iterable[Iterable[Any]]):Unit = {}

  f3(Iterable(Array(123)))    // OK. Takes Iterable[Array[Int]]
Run Code Online (Sandbox Code Playgroud)

但是如果我将Iterable [Array [Int]]赋给局部变量,它不能:

  val v3 = Iterable(Array(123))
  f3(v3)    // Fails to take Takes Iterable[Array[Int]]
Run Code Online (Sandbox Code Playgroud)

有错误:

  Error:(918, 10) type mismatch;
  found   : Iterable[Array[Int]]
  required: Iterable[Iterable[Any]]
  f3(x)
Run Code Online (Sandbox Code Playgroud)

什么是软糖?为什么第一个例子工作,但不是秒.它似乎与嵌套泛型有关:

  def f(o:Iterable[Any]):Unit = {}
  f( Array(123))
  val v1 = Array(123)
  f(v1)  // OK

  def f2(o:Iterable[Any]):Unit = {}
  f2( Iterable(Array(123)))
  val v2 = Array(123)
  f(v2) // OK
Run Code Online (Sandbox Code Playgroud)

用scala.2.11

Ale*_*nov 6

首先,重要的是Array不要扩展Iterable(因为它是Java类型).相反,有从隐式转换Array[A]Iterable[A],所以预计类型的关系.

在第一种情况下:Iterable(Array(123))是一个参数f3,因此是预期类型的​​类型Iterable[Iterable[Any]].所以Array(123)是预期类型的​​typechecked Iterable[Any].好吧,它的实际类型是Array[Int],编译器插入转换(因为Iterable[Int]符合Iterable[Any]).所以这实际上是Iterable(array2iterable(Array(123))(我不记得确切的名字).

在第二种情况下f3有类型Iterable[Array[Int]]:没有什么可以val f3 = ...在行中触发隐式转换,对吧?并且存在从没有隐式转换Iterable[Array[Int]]Iterable[Iterable[Int]](或,更一般地从Iterable[A]Iterable[B]当存在来自隐式转换AB),所以下一行编译失败.您可以自己编写此转换,但转换Array[Array[Int]]为无效Iterable[Iterable[Int]].

当然,如果你使用Iterable[Any],再没有什么可以触发隐式转换!