2015-06-11 5 views
5

Sto appena iniziando a imparare il clojure e sto leggendo alcuni semplici esempi e poi ho fatto del mio meglio per rtfm per i concetti.Che cosa clojure 'val' restituisce questo valore?

Tuttavia, sono un po 'confuso da ciò che val sta facendo nell'esempio seguente. Questo è stato preso dagli esempi di Clojure doc per val.

(first {:one :two}) ;; => [:one :two] 

Qui, un hash-map con una chiave di :one e un valore di :two viene passato al first. Dietro le quinte, Clojure converte questo hash-map in uno sequence di vectors. Dato che c'è solo uno vector in questo sequence, restituisce [:one :two].

(val (first {:one :two})) ;; => :two 
(val [:one :two]) ;; => ClassCastException clojure.lang.PersistentVector cannot be cast to java.util.Map$Entry 
(val {:one :two}) ;; => ClassCastException clojure.lang.PersistentArrayMap cannot be cast to java.util.Map$Entry 

se provo a chiamare val su un (credo) un hash-map (mi rendo conto che in realtà è una "mappa di matrice permanente"), ottengo l'eccezione come visto sopra.

Sono anche confuso dal seguente:

(first {:one :two}) ;; # => [:one :two] (this is a vector right?) 
(val [:one :two]) ;; # => ClassCastException (why doesn't this give back the same result as the example above?) 

Perché non posso semplicemente collegare il risultato di (first {:one :two}) in val e ottenere lo stesso risultato?


Inoltre, un altro esempio elencati nella pagina è la seguente:

(map val {:a 1 :b 2}) ;; => (1 2) 

Ecco come ho letto la linea. Prendi lo array-map{:a 1 :b 2}. Per ciascuna coppia valore-chiave, chiamare val sulla coppia per restituire il valore. Restituire un sequence dalle chiamate risultanti a map. È questo il modo corretto di leggere il problema?

Come sempre, grazie per qualsiasi aiuto.

+3

Una voce di mappa è un vettore, ma non tutti i vettori sono voci di mappa. 'val' funziona solo sulle voci della mappa. – noisesmith

+1

... to wit, '(digita (first {: one: two}))' => 'clojure.lang.MapEntry' – Thumbnail

risposta

6

una sequenza di una mappa produce MapEntry valori avete notato, che sembrano e possono essere confrontati con vettori

user=> (= (first {:a 1 :b 2}) [:a 1]) 
true 

ma non sono la stessa classe

user=> (= (class (first {:a 1 :b 2})) (class [:a 1])) 
false 

Quindi, anche se l'uscita sul repl di (first {:a 1}) si presenta come un vettore, non è, è un MapEntry, in modo che può essere passato a val, ma il vettore [:a 1] non può, quindi, l'eccezione di classe cast.

La tua lettura di ciò che sta facendo la mappa è corretta ad un livello alto, un po 'più specifica potrebbe essere "Per ogni voce nella sequenza da {: a 1: b 2} (che sono valori MapEntry) chiama la funzione val su ogni oggetto (un MapEntry) e genera una sequenza dai risultati ".

Ciò spiega perché una cosa del genere

user=> (map val '([:a 1] [:b 2])) 

farà sì che gli stessi ClassCastException s come la sequenza genera Vector elementi, non MapEntry elementi.

5

val restituisce il valore di una voce della mappa, non una mappa.

(first {:one :two}) ritorno la prima voce della mappa (anche se sembra essere solo un vec)

(map val {:one :two}) ritorno il valore di ogni voce, ed è equivalente al (vals {:one :two})

2
(first {:one :two}) ;; # => [:one :two] (this is a vector right? No, it's not.) 

[:one :two] in questo caso è un MapEntry, non un vettore.

Problemi correlati