clojure代码示例中的这个函数定义是做什么的?

use*_*116 4 functional-programming clojure higher-order-functions

我跟随'Clojure in Action'并且我对此感到困惑:

(defn with-log [function-to-call log-statement ]
      (fn [& args]
          (println log-statement)
          (apply  function-to-call args)))
Run Code Online (Sandbox Code Playgroud)

这是令我困惑的代码段.这是我到目前为止可以破译的内容:

(defn with-log [function-to-call log-statement] ..)定义一个名为"with-log"的函数,该函数接受参数'function-to-call'和'log-statement'以及函数to-to- call是一个作为参数传递给该函数的函数.下一节让我感到困惑:(fn [&args] ....是一个在这里定义的匿名函数吗?'with-log'函数是否返回一个新的函数定义?

(fn [& args]
          (println log-statement)
          (apply  function-to-call args))
Run Code Online (Sandbox Code Playgroud)

所以通过调用(with-log somefunc"my label") - 它是否只是一个新的匿名函数?或者它是否调用匿名函数?

Sim*_*onD 6

with-log将产生一个函数,当被调用时,它将完全执行function-to-call所做的操作,除非使用给予匿名函数的参数评估将在之前log-statement打印的副作用.*out*function-to-call

这是装饰器模式的一个示例- 通过将其包装在另一个函数(即with-log使用该(fn ...)表单创建的匿名函数)中来扩展现有函数的行为.

为了使装饰器函数with-log能够与任何可想象的一起工作,function-to-call指定了匿名函数的参数列表,以便可以使用多个参数调用它(fn [& args] ...).当匿名函数调用function-to-call它时,用函数"解包"参数列表apply.

使用方法with-log可能是:

((with-log some-fn "Calling some-fn") arg1 arg2)
Run Code Online (Sandbox Code Playgroud)

要么

(defn my-fn [a b]
  (+ a b))
(def my-fn-with-logging (with-log my-fn "Calling my-fn"))

(my-fn 1 2) ; evaluates to 3
(my-fn-with-logging 1 2) ; prints "Calling my-fn" and evaluates to 3 
Run Code Online (Sandbox Code Playgroud)