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") - 它是否只是一个新的匿名函数?或者它是否调用匿名函数?
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)