Clojure中的模式匹配功能?

Clojure中的模式匹配功能?,clojure,design-patterns,matching,Clojure,Design Patterns,Matching,我以前使用过erlang,它有一些非常有用的功能,比如模式匹配函数或“函数卫士”。erlang文档中的示例如下: fact(N) when N>0 -> N * fact(N-1); fact(0) -> 1. 但这可以扩展到一个更复杂的例子,其中参数的形式和其中的值是匹配的 clojure中有类似的功能吗?是clojure的一个功能齐全、可扩展的模式匹配库。使用一点宏魔法,您可能会得到与所需内容非常接近的近似值。在core.match

我以前使用过erlang,它有一些非常有用的功能,比如模式匹配函数或“函数卫士”。erlang文档中的示例如下:

fact(N) when N>0 -> 
    N * fact(N-1); 
fact(0) ->      
    1.    
但这可以扩展到一个更复杂的例子,其中参数的形式和其中的值是匹配的


clojure中有类似的功能吗?

是clojure的一个功能齐全、可扩展的模式匹配库。使用一点宏魔法,您可能会得到与所需内容非常接近的近似值。

在core.match()库中正在进行统一的工作


另一种常见的方法是使用defmulti/defmethod对任意函数进行分派,具体取决于您想要执行的操作。请参见(该页底部是阶乘示例)

此外,如果您只想分解向量和映射(实际上是序列或映射的任何事物,例如记录)等简单结构,您也可以使用。这是一种较弱的模式匹配形式,但仍然非常有用。尽管在那里的
let
一节中有描述,但它可以在许多上下文中使用,包括函数定义。

我想介绍的是,它是一个宏,用于定义具有模式匹配的函数,就像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)))

更多信息请参见

对于真正的模式匹配来说,解构有点太有限了。core.match几乎正是我在代码级别上寻找的,这是1.3核心的一部分吗(我不太清楚clojure打包是如何工作的)?对于一些宏,我认为可以将语法扩展到函数(erlang中的IMHO最清晰的代码可以使用带卫士的模式匹配函数编写),它需要1.3,但默认情况下不是1.3的一部分。如果您使用的是Leiningen()--您应该这样做--那么您可以在project.clj的依赖项中添加一行“[org.clojure/core.match”0.2.0-alpha8“]”,然后运行lein deps。是的,正如您在github页面底部看到的,开发人员计划很快将core.match应用于函数(谓词分派)。如果其他人在模式匹配函数参数时遇到问题,请使用
vec
:这太好了!祝这个项目好运,我相信它会帮助很多人,因为模式匹配函数是编程中最被低估的事情之一。@killme2008,我真的很喜欢你对defun的工作。与core.match相比,defun有什么优势?这是一个老问题,但这个项目将core.match扩展到了函数,这几乎正是我多年前提出的问题