2011-04-17 9 views
20

En Clojure, ¿cuál es la forma idiomática de probar nulo y si algo es nulo, entonces sustituirlo por un valor?En clojure cómo elegir un valor si nil

Por ejemplo hago esto mucho:

let [ val (if input-argument input-argument "use default argument")] 

: pero me resulta repetitiva tener que utilizar "entrada-argumento" dos veces.

+0

Si lo hace mucho, en particular, con argumentos de entrada, entonces tal vez usted está sin saber que puede definir [varias firmas] (http://stackoverflow.com/questions/3208347/how-to-create-default-value-for-function-argument-in-clojure) para una función. – coredump

Respuesta

17

sugerencia de "o" es de hecho la forma idiomática para volver a escribir el código de ejemplo, pero tenga en cuenta que no única reemplazará nil valores, sino también a los de Alex que son false.

Si desea mantener el valor false pero deseche nil, se necesita:

(let [val (if (nil? input-argument) "use default argument" input-argument)] 
    ...) 
+0

La respuesta idiomática podría ser, por tanto, probar falsas, en lugar de nulas. Por cierto, como la mayoría del trabajo tiende a realizarse en colecciones, en lugar de verificar un solo valor, la versión del mapa de la respuesta anterior es: (map # (if (nil?%) "This was nil"%) coll) –

+3

Quizás, pero el OP estaba pidiendo la forma idiomática de verificar 'nil'. No puedo comentar cómo debería haber estructurado el código no mostrado que rodea su ejemplo. :-) – sanityinc

67

sólo tiene que utilizar o:

(or input-argument "default") 
+0

Agradable :-). Hubiera hecho algo engorroso con el resultado "if-let [result input-argument]" "default"). Recordaré el o! –

+3

Tenga en cuenta que esto dará el valor "predeterminado" si el argumento de entrada es nulo o falso, que puede no ser el deseado. –

5

Si sólo enlaza la variable que hacer obtener el valor correcto y no lo usa dos veces hay una otra manera lo puede hacer. Hay una función en el núcleo llamada fnil.

Llama al fnil con la función que desea llamar y el argumento predeterminado. Esto devolverá una función que reemplazará nils con el valor predeterminado que proporcionó.

El puede hacer una de las cosas dependiendo de lo que quiera. Crea una función local.

(let [default-fn (fnil fn-you-want-to call "default-argument")] 
(default-fn input-argument)) 

En somecases (donde siempre tienen el mismo argumento por defecto) se puede mover a la lógica de hacer esto fuera de su código y ponerlo donde a la función original (o envoltura de la función en caso de que en una otra biblioteca).

(defn fn-you-want-to-call [arg] ....) 
(def fn-you-want-to-call-default (fnil fn-you-want-to-call "default-argument")) 

Luego, en el código de su reducido a sólo

(fn-you-want-to-call-default input-argument) 

Más usted puede encontrar aquí: http://clojuredocs.org/clojure_core/clojure.core/fnil

Cuestiones relacionadas