学习Clojure:一式三份的NullPointerException
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习Clojure:一式三份的NullPointerException相关的知识,希望对你有一定的参考价值。
我正在Clojure官方网站上使用beginner tutorial。
一项练习要求您执行以下操作:
7)定义一个函数
triplicate
,它接受另一个函数并调用它三次,没有任何参数。
我解决了以下问题:
(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
原因是什么?
答案
恕我直言,最清晰的解决方案是:
(do
(f)
(f)
(f))
评估多个表达式是do
的唯一目的。如果你不想重复切割,最好的方法是:
(dotimes [i 3]
(f))
使用矢量形式会略微模糊重复目标,并暗示您需要3个(f)
的返回值。
脚注:我永远不会使用juxt
,因为它是一个不起眼的功能,会让大多数人挠头并跑到The Clojure CheatSheet查找其定义。
另一答案
问题出在这一部分:((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]
另一答案
(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.
以上是关于学习Clojure:一式三份的NullPointerException的主要内容,如果未能解决你的问题,请参考以下文章