我过去曾使用过erlang,它有一些非常实用的功能,比如模式匹配功能或"功能保护"。来自erlang docs的示例是:
fact(N) when N>0 ->
N * fact(N-1);
fact(0) ->
1.
但是这可以扩展到一个更复杂的例子,其中的参数和值的形式是匹配的。
clojure中有类似的东西吗?
答案 0 :(得分:30)
目前正在努力通过core.match(https://github.com/clojure/core.match)库中的统一来实现这一目标。
根据您想要做什么,另一种常见的方法是使用defmulti / defmethod来调度任意函数。请参阅http://clojuredocs.org/clojure_core/clojure.core/defmulti(该页面底部是因子示例)
答案 1 :(得分:14)
我想介绍defun,它是一个宏来定义模式匹配的函数,就像erlang一样,它基于core.match。上述事实函数可写入:
(use 'defun)
(defun fact
([0] 1)
([(n :guard #(> % 0))]
(* n (fact (dec n)))))
另一个例子,累加器从零到正数n:
(defun accum
([0 ret] ret)
([n ret] (recur (dec n) (+ n ret)))
([n] (recur n 0)))
答案 2 :(得分:9)
core.match是Clojure的全功能和可扩展模式匹配库。有了一点宏观魔法,你可能会非常接近你正在寻找的东西。
答案 3 :(得分:3)
另外,如果你只想拆分像矢量和地图这样的简单结构(任何序列或地图的东西,例如记录,实际上),你也可以使用destructuring bind。这是较弱的模式匹配形式,但仍然非常有用。尽管在let
部分对其进行了描述,但它可以在许多上下文中使用,包括函数定义。