Ant*_*ald 4 clojure clojurescript
说我有这样的功能:
(defn my-f [a & [b]]
(if (nil? b)
(my-other-f a)
(my-other-f a b)))
Run Code Online (Sandbox Code Playgroud)
这当然是一种简化。它是另一个函数的包装函数——实际上 a 是在这个函数内部处理的。如果可选参数 b 没有传递给 my-f,它也不应该传递给 my-other-f。
我正在考虑另一种方法来实现这一目标:
(defn my-f [a & [b]]
(apply my-other-f (make-list-of-not-nil-entries a b)))
Run Code Online (Sandbox Code Playgroud)
是否有内置功能可以完成这项工作?
例子
有时,过于抽象会令人困惑,所以我在这里提供真实案例。以下 ClojureScript 代码有效,其目的显然是尝试不同的浏览器特定选项,以便从 HTML 画布元素获取“webgl”上下文。
(defn create-ctx [canvas & [options]]
(some (if options
#(.getContext canvas % (clj->js options))
#(.getContext canvas %))
["webgl" "experimental-webgl" "webkit-3d" "moz-webgl"]))
Run Code Online (Sandbox Code Playgroud)
给定的 Canvas 元素的方法 getContext 实际上等待一个参数,以及另一个可选的参数。上述包装函数具有相同的数量。
我只是想看看,是否有一种快速的方法来避免 1 和 2 arity 函数调用的显式切换。
我认为您的第一个解决方案在其意图上更具可读性和明确性。它的性能也比带有apply.
如果您仍然想使用apply,则使用的最短解决方案clojure.core是:
(remove nil? [a b])
Run Code Online (Sandbox Code Playgroud)
或者
(keep identity [a b])
Run Code Online (Sandbox Code Playgroud)
或者
(filter some? [a b])
Run Code Online (Sandbox Code Playgroud)
我不知道有任何内置函数接受 varargs 并仅返回非 nil 元素的 seq。你可以创建一个:
(defn non-nils [& args]
(remove nil? args)
Run Code Online (Sandbox Code Playgroud)
或使用ignoring-nils从flatland.useful.fn.
| 归档时间: |
|
| 查看次数: |
2115 次 |
| 最近记录: |