我正在查看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)]
答案 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
,返回值为B
。 Array[A]
遗留了TraversableOnce
,其中A
是TraversableOnce
正在遍历的任何内容(在这种情况下,实际上(A,B)
代表{{1}的不同定义}和A
);虽然它以长格式填充B
,但它仍然使用(A,B)
作为新的返回变量,而不是B
之类的其他字母。
有点混乱!它实际应该阅读
C
,简短形式应为
def toArray[C >: (A,B)](...[C]): Array[C]
就像你期望的那样。