In Clojure what is the idiomatic way to test for nil and if something is nil then to substitute a value?
For example I do this a lot:
let [ val (if input-argument input-argument "use default argument开发者_如何学Go")]
: but I find it repetitive having to use "input-argument" twice.
just use or:
(or input-argument "default")
Alex's suggestion of "or" is indeed the idiomatic way to rewrite your example code, but note that it will not only replace nil
values, but also those which are false
.
If you want to keep the value false
but discard nil
, you need:
(let [val (if (nil? input-argument) "use default argument" input-argument)]
...)
If you only bind the variable to do get the right value and not to use it twice there is a other way you can do it. There is a function in core called fnil
.
You call fnil
with the function you want to call and the default argument. This will return a function that will replace nils with the default value you provided.
The you can do one of the things depending on what you want. Creat a local function.
(let [default-fn (fnil fn-you-want-to call "default-argument")]
(default-fn input-argument))
In somecases (where you always have the same default argument) you can move to logic to do this out of your code and put it where to original function was (or wrap the function in case it in a other library).
(defn fn-you-want-to-call [arg] ....)
(def fn-you-want-to-call-default (fnil fn-you-want-to-call "default-argument"))
Then in your code its reduced to just
(fn-you-want-to-call-default input-argument)
More you can find here: http://clojuredocs.org/clojure_core/clojure.core/fnil
When the expected value is a boolean I recommend using an util fn.
(defn- if-nil [default val]
(if (nil? val)
default
val))
(if-nil true (possible-false input))
精彩评论