为什么scaladoc说HashMap.toArray返回Array [A]而不是Array [(A,B)]?

时间:2013-06-24 14:30:03

标签: scala scaladoc

我正在查看toArray的哈希映射定义:

http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.HashMap

它有

toArray: Array[A]
def toArray[B >: (A, B)](implicit arg0: ClassTag[B]): Array[B]

我不太明白这一点 - 第一位说你得到一个数组[A],但第二部分说你得到数组[B]?这些都不是我所期望的 - 数组[(A,B)]

当我自己检查时:

scala> val x = scala.collection.mutable.HashMap[String, Int]()
x: scala.collection.mutable.HashMap[String,Int] = Map()

scala> x.put("8", 7)
res0: Option[Int] = None

scala> x foreach println
(8,7)

scala> x.toArray
res2: Array[(String, Int)] = Array((8,7))

为什么不喜欢toList?

toList: scala.List[(A, B)]

3 个答案:

答案 0 :(得分:5)

scaladoc有各种各样的微妙错误。这里的问题是你看到方法签名的“简化”版本(意味着传达签名的基本部分并在CanBuildFrom / {{1中隐藏诸如map之类的内容)方法,这实际上是一个实现细节)。 简化在这里有点不对,似乎没有多大意义。 如果单击“完整签名”链接,您将看到真正的签名如下:

flatMap

实际上这仍然是错误的,因为我们当然不能有B类型的B> :( A,B)。它应该更像是:

def toArray[B >: (A, B)](implicit arg0: ClassTag[B]): Array[B]

问题是实际上有两个def toArray[C >: (A, B)](implicit arg0: ClassTag[C]): Array[C] :第一个来自B类声明本身(HashMap)而另一个来自方法{{1在其基类中定义 HashMap[A, +B]toArray)。恰好scaladoc生成器无法对TraversableOnce

的两个实例进行重复删除

答案 1 :(得分:2)

您在toArray的Scaladoc中看到的API:

def toArray[B >: (A, B)](implicit arg0: ClassTag[B]): Array[B]

相当于:

def toArray[C >: (A, B)](implicit arg0: ClassTag[C]): Array[C]

类型变量B的选择确实很不幸(甚至可能是Scaladoc错误,我不确定你是否被允许写这个错误。)

它基本上意味着您将获得(A,B) 的最具体超类型的数组,ClassTag可用。创建ClassTag

需要Array

这基本上意味着如果在编译时,您正在转换的Map的运行时类型是完全已知的,那么您将获得Array[(A,B)]。但是,如果您在某处上升了Map,则生成的Array的运行时类型将取决于上转类型,而不取决于运行时类型。这个 的行为与toList不同,并且由于JVM限制了如何创建原生数组。

答案 2 :(得分:1)

Scaladoc是错误的,因为它从toArray继承TraversableOnce,其中集合的类型为A,返回值为BArray[A]遗留了TraversableOnce,其中ATraversableOnce正在遍历的任何内容(在这种情况下,实际上(A,B)代表{{1}的不同定义}和A);虽然它以长格式填充B,但它仍然使用(A,B)作为新的返回变量,而不是B之类的其他字母。

有点混乱!它实际应该阅读

C

,简短形式应为

def toArray[C >: (A,B)](...[C]): Array[C]

就像你期望的那样。