说我有这样的功能:
(defn my-f [a & [b]]
(if (nil? b)
(my-other-f a)
(my-other-f a b)))
这当然是一种简化。它是另一个函数的包装函数 - 实际上是在这个函数中处理的。 如果可选参数b未传递给my-f,则也不应将其传递给my-other-f。
我在想另一种方法来实现这个目标:
(defn my-f [a & [b]]
(apply my-other-f (make-list-of-not-nil-entries a b)))
是否有内置功能可以完成这项工作?
示例
有时候,过于抽象是令人困惑的,所以我在这里提供真实的案例。以下ClojureScript代码有效,它的目的显然是尝试不同的浏览器特定选项,以获得" webgl" HTML画布元素的上下文。
(defn create-ctx [canvas & [options]]
(some (if options
#(.getContext canvas % (clj->js options))
#(.getContext canvas %))
["webgl" "experimental-webgl" "webkit-3d" "moz-webgl"]))
给定的Canvas元素方法getContext实际上等待一个参数,另一个是可选的。上面的包装函数具有相同的功能。
我只是想看看,如果有一种快速方法可以避免显式切换1和2 arity函数调用。
答案 0 :(得分:3)
我认为你的第一个解决方案对其意图更具可读性和明确性。它也会比apply
具有更好的性能。
如果您仍想使用apply
,那么使用clojure.core
的最短解决方案将是:
(remove nil? [a b])
或者
(keep identity [a b])
或者
(filter some? [a b])
我不知道任何内置函数,它接受varargs并返回一个只有非零元素的seq。你可以创建一个:
(defn non-nils [& args]
(remove nil? args)
或使用flatland.useful.fn
中的ignoring-nils
。