简体   繁体   English

为什么列出 <Object[]> 需要显式转换才能转换为Scala集合?

[英]Why does List<Object[]> needs explicit casting to convert into Scala collection?

Say I have the following Java collection: 说我有以下Java集合:

public static List<Object[]> javaStuff = new ArrayList<Object[]>();

And that, from Scala, I want to refer to that collection, convert it Scala collection and return an Iterator[] over it. 而且,我想从Scala中引用该集合,将其转换为Scala集合,然后在其上返回Iterator[]

Can anyone explain to me why the following (toy) code does not compile? 谁能向我解释为什么以下(玩具)代码无法编译?

def convertMethod[Array[AnyRef]]() : Iterator[Array[AnyRef]] = {
   import scala.collection.JavaConverters._
   val r: mutable.Buffer[Array[AnyRef]] = MyTestClass.javaStuff.asScala // This does not compile!  
   r.iterator
}

More specifically, the error IntelliJ highlights is: 更具体地说,IntelliJ突出显示的错误是:
Expression of type Buffer[Array[AnyRef]] does not conform to expected type Buffer[Array[AnyRef]]

...which was quite uninformative. ...这是毫无根据的 Trying to run the code, the error is a bit more helpful: 尝试运行代码时,该错误会有所帮助:

Error:(18, 58) type mismatch;
found   : scala.collection.mutable.Buffer[scala.Array[Object]]
required: scala.collection.mutable.Buffer[Array[AnyRef]]
   val r: mutable.Buffer[Array[AnyRef]] = MyTestClass.javaStuff.asScala
                                 ^

At which point, I changed the original code into: 在这一点上,我将原始代码更改为:

def convertMethod[Array[AnyRef]]() : Iterator[Array[AnyRef]] = {
   import scala.collection.JavaConverters._
   val r: mutable.Buffer[Array[AnyRef]] = MyTestClass.javaStuff.asScala.map(_.asInstanceOf[Array[AnyRef]])
   r.iterator
 }

...and it worked! ...而且有效!

Now my question really is: why is this necessary? 现在我的问题确实是:为什么这是必要的? Is there a way to avoid that explicit casting? 有没有一种方法可以避免这种显式转换?

The reason is simple. 原因很简单。 In convertMethod , Array is a type parameter and thus does not refer to scala.Array at all. convertMethodArray是类型参数,因此根本引用scala.Array

You should change this: 您应该更改此:

def convertMethod[Array[AnyRef]]()

to this: 对此:

def convertMethod()

Note that contrary to what shadowlands said in a comment, scala.Array really is the same thing as a java array (except for the fact that scala arrays are not covariant, but it does not come into play here). 请注意,与scala.Array在评论中所说的相反, scala.Array实际上与java数组是一样的(除了scala数组不是协变的,但它不在这里起作用)。

Change 更改

def convertMethod[Array[AnyRef]]() =

to

def convertMethod() =

The first one creates a method that takes a type parameter with name Array , which by itself takes a type parameter of name AnyRef (ie a higher kinded type). 第一个创建一个方法,该方法采用名称为Array的类型参数,该方法本身采用名称为AnyRef的类型参数(即,更高种类的类型)。 These newly introduced names hide the built in types Array and AnyRef . 这些新引入的名称隐藏了内置类型ArrayAnyRef

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM