Inizierò spiegando cosa intendo in particolare.
Sfondo
In Javascript, gli array fanno tutto (più o meno un tratto Lispy). Non solo puoi inizializzare, spingere e far apparire, ma puoi anche scorrere, filtrare, ridurre, trasmettere e così via. Puoi anche controllare includes
(contiene), e con l'overload fornito da librerie enormi come lodash, il cielo è il limite.
La musica si interrompe quando arrivi a un linguaggio strongmente tipizzato come Rust, dove HashSet
, HashMap
, Vec
, Array
e Iterator
sono tutte bestie diverse, ciascuna con le proprie capacità e costi . Non puoi iniziare con una "cosa in ascesa" e chiamare tutti i metodi che ti rendi conto di aver bisogno in questo momento.
Esempio di contrived
Ecco un esempio: diciamo che ho un mucchio di Foo
di strutture con un membro Vec
things
. Voglio ottenere solo Foo
s dove things
include gli elementi specifici che sto cercando.
In Javascript o in un linguaggio simile (ad esempio, Clojure, ClojureScript), potrei prendere un array di Foo
s e chiamare .filter((foo) => foo.things.includes(target_element))
. Quindi ottengo la conservazione dell'ordine di things
per Foo
e il controllo di appartenenza di things
per il mio elemento di destinazione. (Immutable.JS ha OrderedMap
pari, che cancella il giglio.)
D'altra parte, in Rust, ho bisogno di usare un HashMap
per has()
, ma un array o Vec
per conservare l'ordine di things
.
Potrei maneggiare una funzione vec_contains
che chiama filter(|this_foo| this_foo.things.as_slice().contains(target_element)).collect().len() > 0
su things
in Rust, ma ora ho una ricerca lineare e un array che si apre. Mi sembra di combattere il sistema dei tipi.
Domanda
Come tieni fuori dai guai quando usi tipi di raccolta strongmente specializzati in una lingua?