2013-06-24 2 views
5

Ich war bei der Definition von toArray für Hashmaps suchen:Warum sagt das Scaladoc, dass HashMap.toArray Array [A] anstelle von Array [(A, B)] zurückgibt?

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

Es hat

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

ich das nicht ganz verstehen - das erste Bit sagt ein Array erhalten [A] , aber der zweite Teil sagt, du bekommst Array [B]? Keiner von ihnen sind das, was ich erwarte - Array [(A, B)]

Wenn ich schau es mir:

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)) 

warum ist es nicht so ToList?

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

nicht alle dedualisierten konnte. – Austin

Antwort

5

Das Scaladoc hat alle Arten von kleinen Fehlern. Das Problem hier ist, dass Sie die "vereinfachte" Version der Methodensignatur sehen (gemeint ist eine Möglichkeit, den wesentlichen Teil der Signatur zu vermitteln und Dinge wie CanBuildFrom in map/flatMap Methoden zu verbergen, die wirklich ein Implementierungsdetail sind). Die Vereinfachung wurde hier ein wenig schief und scheint nicht viel Sinn zu machen. Wenn Sie auf die „volle Unterschrift“ Link klicken, sehen Sie, dass die wirkliche Signatur wie folgt aussieht:

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

In der Tat ist dies immer noch falsch ist, wie wir schon gar nicht einen Typ B haben können, wo B>: (A, B). Es sollte mehr wie:

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

Das Problem ist, dass es eigentlich zwei B s sind: Die erste stammt aus der HashMap Klassendeklaration selbst (HashMap[A, +B]), während der andere von den Methoden kommt toArray in seiner Basis definiert Klasse TraversableOnce (def toArray[B >: A](implicit arg0: ClassTag[B]): Array[B]). Es kommt einfach vor, dass der Scaladoc-Generator die beiden Instanzen B

2

Die API Sie in der Scaladoc von toArray sehen:

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

entspricht:

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

Die Wahl des Typs Variable B in der Tat bedauerlich ist (und vielleicht sogar ein Scaladoc - Bug, ich bin mir nicht sicher, ob du das schreiben darfst).

Im Grunde bedeutet es finden Sie eine Reihe der speziellsten geordneter Typ von (A,B), für die bekommen ein ClassTag verfügbar ist. Die ClassTag wird benötigt, um die Array zu erstellen.

Dies bedeutet im Grunde, dass, wenn zur Laufzeit der Laufzeit-Typ der Map konvertieren Sie vollständig bekannt ist, erhalten Sie eine Array[(A,B)]. Wenn Sie jedoch Ihre Map an einer anderen Stelle erstellt haben, hängt der Laufzeittyp der resultierenden Array von dem heraufgestuften Typ und nicht vom Laufzeittyp ab. Diese ist anderes Verhalten als toList und aufgrund der JVMs Einschränkungen, wie native Arrays erstellt werden können.

1

Die Scaladoc ist einfach falsch, weil es toArray von TraversableOnce erbt, in dem die Art der Sammlung A ist und der Rückgabewert ist B. Die Array[A] Sache ist übrig von TraversableOnce wo A was auch immer TraversableOnce ist traversing (in diesem Fall eigentlich (A,B) für eine andere Definition von A und B); und obwohl es die (A,B) in richtig in der langen Form füllt, verwendet es immer noch B als die neue Rückgabevariable anstelle eines anderen Buchstabens wie C.

Art von verwirrend! Es sollte eigentlich

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

und die Kurzform sollte

toArray: Array[(A,B)] 

wie Sie erwarten, lesen sein.

Verwandte Themen