【问题标题】:multiple functions with same name in clojureclojure中具有相同名称的多个函数
【发布时间】:2014-08-27 08:51:34
【问题描述】:
(defn hi[](+ 5 6))  
(hi)  
(defn hi[](+ 6 7))  
(hi) 

嗨, 我是clojure的新手。正如上面写的代码,我写了两个同名的函数。 我们可以在clojure中为多个函数使用相同的名称吗?如果是,它是否在相同的命名空间内发生冲突?

【问题讨论】:

  • 你期待什么?
  • 你想达到什么目的?
  • 我只是在检查编写多个同名函数是否正确。如果我有执行不同操作并具有相同函数名称的函数怎么办?
  • 如果功能不同,它们应该有不同的名称。
  • 第二个defn 覆盖第一个。

标签: clojure


【解决方案1】:

在同一个命名空间中不能有多个同名的函数。如果你定义函数foo,然后重新定义它,新版本将替换旧版本。

不太清楚您要实现什么,但 Clojure 有很多方法可以在一个名称下拥有多个实现。

Arity 调度

您可以在 arity 上调度函数:

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

同一个函数的不同元素可以相互调用,这在某种程度上相当于有多个同名的函数。

多种方法

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

(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)

【讨论】:

  • 另外,你可能对这个question感兴趣。
【解决方案2】:

我写了两个同名的函数。

是和否:

  • 您编写了两个同名的函数定义。
  • 第二个定义覆盖了第一个。
  • 函数从不共享名称。

clojure 中的多个函数可以同名吗?

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

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

如果是,是否在同一个命名空间内冲突?

是的。

但是……

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


函数定义是评估defn副作用。我所知道的关于 lisps evaluate 函数定义的最佳解释是 Paul Graham's On Lisp 的第 2 章。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多