学习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的主要内容,如果未能解决你的问题,请参考以下文章

erp供应链怎么拷贝生成采购订单

pdi检测记录哪里查

怎么用wps实现每打印一次发货单号数值自动增加1的效果?

500份的数据0-1分布用啥模型好

今日份的学习笔记:2021.08.12

Clojure 学习笔记 1