J'ai lu que les vecteurs ne sont pas des séquences, mais les listes le sont. Je ne sais pas quelle est la raison d'être de l'un sur l'autre. Il semble que les vecteurs soient les plus utilisés, mais y a-t-il une raison à cela?
Encore une fois, il semble que j'ai répondu à ma propre question en m'impatientant et en la posant dans #clojure sur Freenode. C'est une bonne chose de répondre à vos propres questions sur Stackoverflow.com: D
J'ai eu une discussion rapide avec Rich Hickey, et voici l'essentiel.
[12:21] <Raynes> Vectors aren't seqs, right?
[12:21] <rhickey> Raynes: no, but they are sequential
[12:21] <rhickey> ,(sequential? [1 2 3])
[12:21] <clojurebot> true
[12:22] <Raynes> When would you want to use a list over a vector?
[12:22] <rhickey> when generating code, when generating back-to-front
[12:23] <rhickey> not too often in Clojure
Si vous avez beaucoup programmé Java et que vous connaissez le cadre de collecte Java, pensez à des listes comme LinkedList
et à des vecteurs) comme ArrayList
. Vous pouvez donc à peu près choisir les conteneurs de la même manière.
Pour plus de précision: si vous avez l'intention d'ajouter beaucoup d'éléments individuellement au début ou à l'arrière de la séquence, une liste chaînée est bien meilleure qu'un vecteur, car les éléments n'ont pas besoin d'être mélangés à chaque fois. Cependant, si vous souhaitez accéder à des éléments spécifiques (pas près du début ou de l'arrière de la liste) fréquemment (c'est-à-dire un accès aléatoire), vous voudrez utiliser le vecteur.
Soit dit en passant, les vecteurs peuvent facilement être transformés en séquences.
user=> (def v (vector 1 2 3))
#'user/v
user=> v
[1 2 3]
user=> (seq v)
(1 2 3)
user=> (rseq v)
(3 2 1)
Les vecteurs ont O(1) temps d'accès aléatoires, mais ils doivent être préalloués. Les listes peuvent être étendues dynamiquement, mais l'accès à un élément aléatoire est O (n).
Quand utiliser un vecteur:
Quand utiliser une liste:
juste une petite note:
"J'ai lu que les vecteurs ne sont pas des séquences, mais les listes le sont."
les séquences sont plus génériques que les listes ou les vecteurs (ou les cartes ou les ensembles).
Son regrettable que le REPL imprime les listes et les séquences de la même car cela donne vraiment l'impression que les listes sont des séquences même si elles sont différentes. la fonction (seq) créera une séquence à partir de beaucoup de choses différentes, y compris des listes, et vous pouvez ensuite alimenter cette séquence à n'importe quelle pléthore de fonctions qui font des choses astucieuses avec des séquences.
user> (class (list 1 2 3))
clojure.lang.PersistentList
user> (class (seq (list 1 2 3)))
clojure.lang.PersistentList
user> (class (seq [1 2 3]))
clojure.lang.PersistentVector$ChunkedSeq
Sec a un raccourci qui renvoie son argument s'il s'agit déjà d'une séquence:
user> (let [alist (list 1 2 3)] (identical? alist (seq alist)))
true
user> (identical? (list 1 2 3) (seq (list 1 2 3)))
false
static public ISeq seq(Object coll){
if(coll instanceof ASeq)
return (ASeq) coll;
else if(coll instanceof LazySeq)
return ((LazySeq) coll).seq();
else
return seqFrom(coll);
}
les listes sont des séquences, bien que d'autres choses le soient aussi, et toutes les séquences ne sont pas des listes.