我正在使用Clojure官方网站上的初学者教程。
一个练习要求您进行以下操作:
7)定义一个函数
triplicate
,该功能采用另一个函数并调用3次,而无需任何参数。
我解决了如下:
(defn triplicate [f] ((f) (f) (f)))
问题在于,当使用NullPointerException
时,我无法确定原因。
user=> (triplicate #(println "hello, world"))
hello, world
hello, world
hello, world
NullPointerException user/triplicate (NO_SOURCE_FILE:115)
以下是pst
的输出,如果有用:
user=> (pst)
NullPointerException
user/triplicate (NO_SOURCE_FILE:145)
user/triplicate (NO_SOURCE_FILE:145)
user/eval376 (NO_SOURCE_FILE:146)
user/eval376 (NO_SOURCE_FILE:146)
clojure.lang.Compiler.eval (Compiler.java:7062)
clojure.lang.Compiler.eval (Compiler.java:7025)
clojure.core/eval (core.clj:3206)
clojure.core/eval (core.clj:3202)
clojure.main/repl/read-eval-print--8572/fn--8575 (main.clj:243)
clojure.main/repl/read-eval-print--8572 (main.clj:243)
clojure.main/repl/fn--8581 (main.clj:261)
clojure.main/repl (main.clj:261)
nil
原因是什么?
imho,最清晰的解决方案是:
(do
(f)
(f)
(f))
评估多种表达式是do
的唯一目的。如果您不希望剪切重复,最好的方法是:
(dotimes [i 3]
(f))
使用矢量形式略微掩盖了重复目标,这意味着您需要(f)
的返回值的3个。
脚注:我永远不会使用juxt
,因为它是一个晦涩的功能,它会使大多数人挠头并跑到clojure备忘单以查找其定义。
(defn triplicate [f] ((f) (f) (f)))
返回: (nil nil nil)
事物是 nil 不是函数。调用nil原因 nullpoInterException 。
您可以这样写:
(defn triplicate [f] [(f) (f) (f)])
;;=> [nil nil nil] which is fine, because you are keeping nils in a vector.
问题在此部分: ((f) (f) (f))
此表格表示:"呼叫函数f,然后将其结果称为函数,带有2个参数:f
调用的结果和f
调用的结果"
您可以使用[(f) (f) (f)]
或仅使用juxt
:
user> (def triplicate #(juxt % % %))
#'user/triplicate
user> ((triplicate #(println "hello")))
;;=> hello
;;=> hello
;;=> hello
[nil nil nil]