2009-11-24 5 views
8

Dies ist eher eine Frage von Stil und Vorliebe, aber hier gilt: Wann sollte ich scala.Array verwenden? Ich benutze List die ganze Zeit und gelegentlich in Seq, Map und dergleichen, aber ich habe nie Array in der Wildnis verwendet oder gesehen. Ist es nur für Java-Kompatibilität da? Fehle ich einen gemeinsamen Anwendungsfall?Wann sollte ich Scala's Array anstelle einer der anderen Sammlungen verwenden?

+0

Soll ich dies zu einem Community-Wiki machen? – pr1001

+1

Ich glaube nicht. Die Vor- und Nachteile der Verwendung von Scala's Array sind ziemlich genau definiert und können objektiv diskutiert werden. Die Frage ist gesund, IMHO. –

Antwort

12

Als erstes machen wir hier einen Haftungsausschluss. Scala 2.7's Array versucht, ein Java Array und eine Scala Collection gleichzeitig zu sein. Es gelingt meistens, aber bei einigen Fällen scheitert es an beiden. Leider können diese Fälle mit guten Leuten mit normalem Code passieren, weshalb Scala 2.8 davon abweicht.

Auf Scala 2.8 gibt es Array, die Java Array ist. Das bedeutet, dass es sich um einen zusammenhängenden Speicherbereich handelt, der entweder Referenzen oder Grundelemente speichert (und daher unterschiedliche Elementgrößen haben kann) und auf die nach dem Zufallsprinzip schnell zugegriffen werden kann. Es hat auch lausige Methoden, eine schreckliche toString Implementierung und führt schlecht aus, wenn Generics und Primitive zur gleichen Zeit (zB: def f[T](a: Array[T]) = ...; f(Array(1,2,3))).

Und dann gibt es GenericArray, die eine Scala Collection ist, die von einem Array unterstützt wird. Es speichert immer Boxed-Primitive, so dass es keine Performance-Probleme beim Mischen von Primitiven und Generics hat, aber andererseits nicht die Leistungssteigerungen eines rein primitiven (nicht-generischen) Primitivarrays aufweist.

Also, wann was zu verwenden? Ein Array hat die folgenden Eigenschaften:

  • O (1) zufällige Lese- und Schreib
  • O (n) append/prepend/Einfügen/Löschen
  • wandelbar

Wenn Sie dies nicht tun benötigen Generika, oder Ihre Generika können als [T <: AnyRef] angegeben werden, so dass Primitive, die AnyVal sind, und diese Eigenschaften sind optimal für Ihren Code, dann gehen Sie dafür.

Wenn Sie Generics benötigen, einschließlich Primitiven, und diese Eigenschaften sind optimal für Ihren Code, verwenden Sie GenericArray auf Scala 2.8. Wenn Sie eine echte Sammlung mit all ihren Methoden wünschen, möchten Sie sie möglicherweise auch verwenden, anstatt von impliziten Konvertierungen abhängig zu sein.

Wenn Sie Unveränderlichkeit wollen oder wenn Sie eine gute Leistung zum Anhängen, Vorbereiten, Einfügen oder Löschen benötigen, suchen Sie nach einer anderen Sammlung.

+0

Danke, Daniel, das ist eine großartige Antwort. – pr1001

3

Ein Array ist geeignet, wenn Sie mehrere Elemente derselben (oder kompatiblen) Klasse haben und Sie im Voraus die genaue Anzahl dieser Elemente oder eine vernünftige obere Grenze kennen und an einer schnellen Zufallsauswahl interessiert sind Zugriff und möglicherweise direkte Änderung von Elementen, aber nach dem Einrichten werden Sie niemals Objekte von irgendwo in der Liste einfügen oder entfernen.

Oder auf eine andere Weise ausgedrückt, ist es eine aggregierte Datenstruktur mit weniger Schnickschnack als die Collection-Typen, mit etwas weniger Overhead und etwas bessere Leistung, je nachdem, wie es verwendet wird.

Ein sehr durchdachtes Beispiel: Sie sind in der Produktion von Funktionen tätig, und die Qualitätsprüfung für diese Funktionen beinhaltet die Überprüfung ihrer Leistung oder Ergebnisse für einen Satz von 1000 festen Eingabewerten. Darüber hinaus entscheiden Sie, diese Werte nicht in einer Datei zu belassen, sondern sie in Ihrem Programm fest zu codieren. Ein Array wäre angemessen.

3

Schnittstelle mit Java-APIs ist ein Fall. Im Gegensatz zu Java-Arrays sind Scala-Arrays invariant und haben daher keinen Vorteil gegenüber Listen.

Verwandte Themen