关于评估:何时在clojure中使用`constantly`,如何以及何时评估其参数?

When to use `constantly` in clojure, how and when are its arguments evaluated?

在另一个问题的可接受答案中,在运行时将Clojure设置为"常量"时,将使用clojure函数constantly

constantly的定义如下所示:

1
2
3
4
(defn constantly
 "Returns a function that takes any number of arguments and returns x."
  {:added"1.0"}
  [x] (fn [& args] x))

doc字符串说明了它的作用,但没有说明为什么要使用它。

在上一个问题给出的答案中,经常使用以下方式:

1
2
3
4
5
6
(declare version)

(defn -main
  [& args]
 (alter-var-root #'version (constantly (-> ...)))
 (do-stuff))

因此,不断返回的函数将直接对其结果求值。 我对这很有用感到困惑。 我可能不理解x在不固定地包装在"常数"中的情况下如何被评估。

什么时候应该使用constantly,为什么有必要?


当API需要一个函数并且您只需要一个常量时,constantly函数很有用。 在问题中提供的示例中就是这种情况。

大多数alter-*函数(包括alter-var-root)都采用一个函数,以允许调用者根据其旧值修改某些内容。 即使您只是希望新值是7(忽略旧值),您仍然需要提供一个函数(仅提供7会导致尝试对其求值,但会失败)。 因此,您必须提供一个仅返回7的函数。(constantly 7)仅生成此函数,从而省去了定义它的工作。

编辑:关于问题的第二部分,constantly是一个普通函数,因此在构造常量函数之前先评估其参数。 因此,(constantly @myref)始终会在调用constantly时返回myref引用的值,即使以后更改它也是如此。