为什么scaladoc会说HashMap.toArray返回数组[A],而不是数组[(A,B)]?
我正在查看hashmaps的为什么scaladoc会说HashMap.toArray返回数组[A],而不是数组[(A,B)]?,scala,scaladoc,Scala,Scaladoc,我正在查看hashmaps的toArray定义: 它有 toArray: Array[A] def toArray[B >: (A, B)](implicit arg0: ClassTag[B]): Array[B] 我不太明白这一点-第一位表示得到数组[A],但第二部分表示得到数组[B]?这两个都不是我所期望的-Array[(A,B)] 当我自己检查时: scala> val x = scala.collection.mutable.HashMap[String, Int]()
toArray
定义:
它有
toArray: Array[A]
def toArray[B >: (A, B)](implicit arg0: ClassTag[B]): Array[B]
我不太明白这一点-第一位表示得到数组[A],但第二部分表示得到数组[B]?这两个都不是我所期望的-Array[(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: scala.List[(A, B)]
您在
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)
超类型数组,其中有一个类标签
。创建数组
需要类标签
这基本上意味着,如果在编译时,您正在转换的
映射的运行时类型是完全已知的,那么您将得到一个数组[(a,B)]
。但是,如果您已将映射上溯到某个位置,则生成的数组的运行时类型将取决于上溯类型,而不是运行时类型。这与toList
的行为不同,而且是由于JVM对如何创建本机数组的限制。Scaladoc是错误的,因为它继承了toArray
的toArray
,其中集合的类型是A
,返回值是B
。数组[A]
是TraversableOnce
的遗留物,其中A
是TraversableOnce
正在遍历的对象(在本例中,对于A
和B
的不同定义,实际上是(A,B)
);尽管它以长格式正确地填充(A,B)
,但它仍然使用B
作为新的返回变量,而不是像C
这样的不同字母
有点困惑!实际上应该是
def toArray[C >: (A,B)](...[C]): Array[C]
缩写形式应该是
toArray: Array[(A,B)]
正如您所料。scaladoc有各种各样的细微缺陷。这里的问题是,您看到的是方法签名的“简化”版本(意味着传递签名的基本部分并在map
/flatMap
方法中隐藏诸如CanBuildFrom
之类的内容,这实际上是一个实现细节)。
这里的简化有点错误,似乎没有多大意义。
如果单击“完整签名”链接,您将看到真正的签名如下所示:
def toArray[B >: (A, B)](implicit arg0: ClassTag[B]): Array[B]
事实上,这仍然是错误的,因为我们当然不能有一个类型B,其中B>:(a,B)。它应该更像:
def toArray[C >: (A, B)](implicit arg0: ClassTag[C]): Array[C]
问题是实际上有两个B
s:第一个来自HashMap
类声明本身(HashMap[A,+B]
),而另一个来自其基类中定义的方法toArray
TraversableOnce
(def-toArray[B>:A](隐式arg0:ClassTag[B]):数组[B]
)。恰好scaladoc生成器未能消除B
的两个实例中的重复数据。谢谢!