Il s'agit plus d'une question de style et de préférence, mais voilà: quand devrais-je utiliser scala.Array? J'utilise List tout le temps et parfois je rencontre Seq, Map et autres, mais je n'ai jamais utilisé ni vu Array dans la nature. Est-ce juste là pour la compatibilité Java? Ai-je manqué un cas d'utilisation commun?Quand devrais-je utiliser Scala's Array au lieu de l'une des autres collections?
Répondre
Tout d'abord, faisons un avertissement ici. Scala 2.7 Array
essaie d'être un Java Array
et une collection Scala en même temps. Il réussit le plus souvent, mais échoue à la fois pour certains cas de coin. Malheureusement, ces cas de coin peuvent arriver à de bonnes personnes avec du code normal, donc Scala 2.8 s'en écarte. Sur la Scala 2.8, il y a Array
, Java Array
. Cela signifie que c'est un espace mémoire contigu, qui stocke des références ou des primitives (et, par conséquent, peut avoir des tailles d'éléments différentes), et peut être accédé au hasard assez rapidement. Il a également des méthodes moche, une implémentation horrible toString
, et fonctionne mal lors de l'utilisation de génériques et de primitives en même temps (par exemple: def f[T](a: Array[T]) = ...; f(Array(1,2,3))
).
Et puis, il y a GenericArray
, qui est une collection Scala soutenue par un Array
. Il stocke toujours les primitives en boîte, donc il n'a pas les problèmes de performance lors du mélange des primitives et des génériques mais, d'un autre côté, il n'a pas les gains de performance d'un tableau primitif purement primitif (non générique).
Alors, quand utiliser quoi? Un Array
présente les caractéristiques suivantes:
- O (1) lecture aléatoire et écrire
- O (n) append/précédez/insertion/suppression
- mutable
Si vous n'êtes pas besoin génériques, ou vos génériques peuvent être déclarés comme [T <: AnyRef]
, excluant ainsi les primitives, qui sont AnyVal
, et ces caractéristiques sont optimales pour votre code, alors allez-y.
Si vous avez besoin de génériques, y compris de primitives, et que ces caractéristiques sont optimales pour votre code, utilisez GenericArray
sur Scala 2.8. De plus, si vous voulez une vraie Collection, avec toutes ses méthodes, vous pouvez aussi l'utiliser, au lieu de dépendre des conversions implicites.
Si vous voulez être immuable ou si vous avez besoin de bonnes performances pour l'ajouter, l'ajouter, l'insérer ou le supprimer, recherchez une autre collection.
Merci, Daniel, c'est une bonne réponse. – pr1001
Un tableau est approprié lorsque vous avez un certain nombre d'éléments de la même classe (ou compatible), et vous savez à l'avance le nombre exact de ces éléments, ou une limite supérieure raisonnable, et vous êtes intéressé par aléatoire rapide l'accès et peut-être l'altération sur place des éléments, mais après l'avoir configuré, vous n'insèrerez ou ne supprimerez jamais d'éléments de quelque part dans la liste. Ou autrement dit, il s'agit d'une structure de données agrégée avec moins de cloches et de sifflets que les types de collection, avec un peu moins de frais généraux et une performance légèrement meilleure en fonction de la façon dont il est utilisé.
Un exemple très artificiel: Vous produisez des fonctions et les tests de qualité pour ces fonctions impliquent de vérifier leurs performances ou leurs résultats pour un ensemble de 1000 valeurs d'entrée fixes. De plus, vous décidez de ne pas conserver ces valeurs dans un fichier, mais plutôt de les coder en dur dans votre programme. Un tableau serait approprié.
L'interfaçage avec les API Java est un cas. Contrairement aux tableaux Java, les tableaux scala sont invariants et n'ont donc aucun avantage sur les listes à cause de cela.
Dois-je en faire un wiki communautaire? – pr1001
Je ne pense pas. Les avantages et les inconvénients de l'utilisation de Scala's Array sont assez bien définis, et peuvent être discutés objectivement. La question est solide, à mon humble avis. –