2008-10-09 7 views

Antwort

40

Arrays in Scala sind sehr homogen. Dies liegt daran, dass Scala eine statisch typisierte Sprache ist. Wenn Sie wirklich pseudo-heterogene Merkmale benötigen, müssen Sie eine unveränderliche Datenstruktur verwenden, die kovariant parametrisiert wird (die meisten unveränderlichen Datenstrukturen sind). List ist das kanonische Beispiel dort, aber Vector ist auch eine Option. Dann können Sie etwas tun:

Vector("a string", 10, Map("x" -> 1),()=>()) + "another value" 

Das Ergebnis vom Typ Vector[Any] sein wird. Nicht sehr nützlich in Bezug auf statische Typisierung, aber alles wird wie versprochen dort drin sein.

übrigens die "Literalsyntax" für Arrays in Scala ist wie folgt:

Array(1, 2, 3, 4)  // => Array[Int] containing [1, 2, 3, 4] 

Siehe auch: More info on persistent vectors

+9

Diese Antwort ist sehr verwirrend - Tatsache ist, dass das Beispiel des OP mit einem Scala 'Array' perfekt funktioniert, wie @socs Antwort zeigt. Es gibt andere Optionen wie 'List' und' Vector', aber die Gründe, sie zu verwenden oder nicht zu verwenden, haben nichts damit zu tun, ob der Anwendungsfall homogen oder "pseudo-heterogen" ist. –

+1

Die Antwort ist mit Jargon durchsetzt, die es verwirrend machen kann. Es erklärt auch eine Menge, wenn Sie bekommen, was er sagt. Ich vermute, dass diese Formulierung absichtlich gemacht wurde, da das OP von Javascript kommt. – providence

+4

Nein, das ist wirklich, wie Scala Eingeborene sprechen. Es ist völlig normal. (Und ich meine das ehrlich; ich versuche überhaupt nicht, sarkastisch zu sein.) –

4

Scala könnte die Fähigkeit für eine "heterogene" -Liste bekommen bald : HList in Scala

+3

Man beachte, dass HList die Sprache überhaupt nicht ändert, also wenn HList es kann, war es immer in Scala. –

18

Scala wählt den spezifischsten Array-Elementtyp aus, der gehalten werden kann alle Werte in diesem Fall braucht es die allgemeinste Art Any, die ein übergeordneten Typ von jeder anderen Art ist:

Array("a string", 10, new { val x = 1 },() =>()) :+ "another value" 

Das resultierende Array Array[Any] vom Typ sein.

2

Persönlich würde ich wahrscheinlich Tupel verwenden, wie herom in einem Kommentar erwähnt.

scala> ("a string", 10, (1),() => {}) 
res1: (java.lang.String, Int, Int,() => Unit) = (a string,10,1,<function0>) 

Aber Sie können solche Strukturen nicht einfach anhängen.

Der von ePharaoh erwähnte HList ist "dafür gemacht", aber ich würde mich wahrscheinlich selbst davon freihalten. Es ist schwer in der Typ-Programmierung und kann daher überraschende Lasten mit sich bringen (d. H. Beim Kompilieren eine Menge von Klassen erzeugen). Sei bloß vorsichtig. Ein hList der oben (benötigt MetaScala Bibliothek) würde (nicht bewiesen, da ich MetaScala nicht wichtig):

scala> "a string" :: 10 :: (1) ::() => {} :: HNil 

Sie usw. anhängen (na ja, zumindest prepend) auf eine solche Liste, und es Ich kenne die Typen. Prepending erstellt einen neuen Typ, der den alten Typ als Tail hat.

Dann gibt es einen Ansatz noch nicht erwähnt. Klassen (insbesondere Fallklassen) sind sehr leicht auf Scala und Sie können sie als Einzeiler machen:

scala> case class MyThing(str: String, int: Int, x: Int, f:() => Unit) 
defined class MyThing 

scala> MyThing("a string", 10, 1,()=>{}) 
res2: MyThing = MyThing(a string,10,1,<function0>) 

Natürlich ist dies entweder Anhängen nicht behandelt.

Verwandte Themen