2011-08-02 13 views
19

Citando alegría de Clojure, sección 4.3.1--¿Por qué usar palabras clave o símbolos como funciones para buscar valores desde mapas funciona?

Debido a que las palabras clave son la auto-evaluación y proporcionan controles de igualdad rápidas, son casi siempre se utiliza en el contexto de las claves de mapas. Una razón igualmente importante utilizar palabras clave como claves mapa es que pueden ser utilizados como funciones, teniendo un mapa como argumento, para realizar búsquedas de valor:

(def population {:zombies 2700, :humans 9}) 
(:zombies population) 
;=> 2700 
(println (/ (:zombies population) 
(:humans population)) 
"zombies per capita") 
; 300 zombies per capita 

No es evidente para mí lo que está pasando aquí. De alguna manera (:zombies population) tiene que transformarse en (get population :zombies), ¿verdad? ¿Cómo funciona esto exactamente? La palabra clave se evalúa a sí misma, no a una función. ¿Busca el lector los casos en que lo primero de una lista es una palabra clave y agrega obtener y mover la palabra clave al final de la lista?

Respuesta

22

Cita de official documentation:

Palabras clave implemento IFN durante invoke() de un argumento (un mapa) con un segundo argumento opcional (un valor por defecto). Por ejemplo (: mykey my-hash-map: none) significa lo mismo que (get my-hash-map: mykey: none). Ver get.

Y Clojure puede llamar palabra clave como función, porque implementa la misma interfaz como función. Lo mismo es para los símbolos ...

+0

Curiosamente, el primer argumento no tiene que ser un mapa: (: foo: bar: Baz) se obtiene: Baz – KingCode

+0

@KingCode Si no es un 'ILookup', un' java Mapa ', o un' IPersistentSet', a continuación, '' getFrom' en RT' simplemente devuelve 'null', en cuyo caso el método' invoke' en 'Keyword' simplemente devuelve el valor' notFound', o ': baz' en su ejemplo . – Josh

16

Palabras clave son funciones, en todos los sentidos. No hay magia de lector involucrada, como verá si prueba (let [m {:humans 100}, k :humans] (k m)). Espero que usted estará de acuerdo que no hay manera que el lector podría convertir esto en un encuentro (el compilador podría, pero se puede pretender que he hecho el valor de k depender de una expresión que si el compilador no puede predecir, tales como entrada del usuario).

Debido a que los tipos de datos básicos de Clojure son interfaces y objetos de Java pueden implementar muchas interfaces, una pieza de información puede tener varios tipos. ¿Es una palabra clave? Sí. ¿Es una función? También si:

user> (keyword? :k) 
true 
user> (ifn? :k) 
true 
user> (.invoke :k {:k 1}) 
1 
Cuestiones relacionadas