SQL提供了一个函数coalesce(a, b, c, ...),如果它的所有参数都为null,则返回null,否则返回第一个非null参数.
你会如何在Clojure中写这样的东西?
它将被调用如下:(coalesce f1 f2 f3 ...)其中的fi表单只应在需要时进行评估.如果f1是非零,则f2不应评估 - 它可能有副作用.
也许Clojure已经提供了这样的功能(或宏).
编辑:这是我提出的一个解决方案(修改自Stuart Halloway的Programming Clojure,(and ...)第206页的宏):
(defmacro coalesce
([] nil)
([x] x)
([x & rest] `(let [c# ~x] (if c# c# (coalesce ~@rest)))))
Run Code Online (Sandbox Code Playgroud)
似乎工作.
(defmacro coalesce
([] nil)
([x] x)
([x & rest] `(let [c# ~x] (if (not (nil? c#)) c# (coalesce ~@rest)))))
Run Code Online (Sandbox Code Playgroud)
固定.
nic*_*kik 24
你想要的是"或"宏.
从左到右逐个评估exprs.如果表单返回逻辑true值,或返回该值并且不评估任何其他表达式,否则返回最后一个表达式的值.(或)返回nil.
http://clojuredocs.org/clojure_core/clojure.core/or
如果您只想要nil而不是false,请重写并命名为coalesce.
编辑:
这不能作为函数完成,因为函数首先评估所有参数.这可以在Haskell中完成,因为函数是懒惰的(不是100%肯定Haskell的事情).
基于 nickik 的回答和“或”clojure 宏:
(defmacro coalesce
([] nil)
([x] x)
([x & next]
`(let [v# ~x]
(if (not (nil? v#)) v# (coalesce ~@next)))))
Run Code Online (Sandbox Code Playgroud)