clojure中具有相同名称的多个函数

时间:2014-08-27 08:51:34

标签: clojure

(defn hi[](+ 5 6))  
(hi)  
(defn hi[](+ 6 7))  
(hi) 

您好, 我是clojure的新手。如上所述,我写了两个同名的函数。 我们可以在clojure中为多个函数使用相同的名称。如果是,它是否在相同的名称空间内冲突?

2 个答案:

答案 0 :(得分:7)

在同一名称空间中不能有多个具有相同名称的函数。如果您定义函数foo然后再次重新定义它,则较新的版本将替换旧版本。

目前还不太清楚你想要实现的目标,但Clojure有很多方法可以在一个名称下实现多个实现。

Arity Dispatch

您可以在arity上发送函数:

(defn foo
  ([x] :version-one)
  ([x y] :version-two)
  ([x y & more] :version-tree))

同一个函数的不同arities可以相互调用,这有点等同于具有多个具有相同名称的函数。

多方法

您可以使用multimethods进行调度。它们允许您定义将在参数上调用的函数,其结果将用于调度。

(defmulti foo odd?)

(defmethod foo true [x]
  (format "look, ma, %d is odd!" x))

(defmethod foo false [x]
  (format "look, ma, %d is even!" x))

协议

这种技术类似于其他语言的多态性。您可以调度参数类型。这是一个例子:

(defprotocol foo
  (my-fnc [x] "description..."))

(extend-protocol foo
  Number
  (my-fnc [x] :number-version)
  String
  (my-fnc [x] :string-version))

Multimethods是最强大的工具,您可以通过这种方式模拟协议:

(defmulti foo class)

答案 1 :(得分:1)

我写了两个同名的函数。

是和否:

  • 您编写了两个具有相同名称的函数定义。
  • 第二个定义覆盖了第一个。
  • 这些功能永远不会共享名称。

我们可以在clojure中为多个函数使用相同的名称吗?

不在同一名称空间中。符号的第二个defdefn会删除第一个符号。

  • 命名空间中只有一个具有给定名称的符号。
  • 符号一次只能引用一个var
  • The def form将符号与其引用的var联系起来。
  • The fn form创建一个函数。
  • defn宏是deffn表单的包装器, 导致命名符号引用持有该函数的var
  • 不同名称空间中具有相同名称的符号不会发生冲突: 它们是不同的符号。

如果是,它在同一名称空间内发生冲突吗?

是。

但是......

一个函数可以有多个arities - 参数计数。这适用于由符号通过变量和其他上下文引用的函数。


功能定义是评估defn副作用。我知道lisps 如何评估函数定义的最佳解释是Paul Graham's On Lisp的第2章。