【问题标题】:Clojure null pointer exceptionClojure 空指针异常
【发布时间】:2017-09-25 04:11:56
【问题描述】:

我有以下代码

(def lampo1 [-20 -18 -30 -5 7 15 25 18 7 0 -15 -10])
(def lampo2 [-21 -11 -31 -5 8 16 35 18 1 2 -15 -20])

(defn -main
  [& args]

  (let [keskiarvot (map #(/ (reduce + %) (count %)) (map vector lampo1 lampo2))] (
    (println keskiarvot)

    (let [positiiviset (filter pos? keskiarvot)](
      (println positiiviset)

      (let [posKeskiarvo (double (/ (reduce + positiiviset) (count positiiviset)))](
        (println posKeskiarvo))))))))

输出如下

(-41/2 -29/2 -61/2 -5 15/2 31/2 30 18 4 1 -15 -15)
(15/2 31/2 30 18 4 1)
12.66666666666667
Exception in thread "main" java.lang.NullPointerException, compiling:(/tmp/form-init1433117969168569713.clj:1:73)
        at clojure.lang.Compiler.load(Compiler.java:7391)
        at clojure.lang.Compiler.loadFile(Compiler.java:7317)
        at clojure.main$load_script.invokeStatic(main.clj:275)
        at clojure.main$init_opt.invokeStatic(main.clj:277)
        at clojure.main$init_opt.invoke(main.clj:277)
        at clojure.main$initialize.invokeStatic(main.clj:308)
        at clojure.main$null_opt.invokeStatic(main.clj:342)
        at clojure.main$null_opt.invoke(main.clj:339)
        at clojure.main$main.invokeStatic(main.clj:421)
        at clojure.main$main.doInvoke(main.clj:384)
        at clojure.lang.RestFn.invoke(RestFn.java:421)
        at clojure.lang.Var.invoke(Var.java:383)
        at clojure.lang.AFn.applyToHelper(AFn.java:156)
        at clojure.lang.Var.applyTo(Var.java:700)
        at clojure.main.main(main.java:37)
Caused by: java.lang.NullPointerException
        at v501.core$_main.invokeStatic(core.clj:16)
        at v501.core$_main.doInvoke(core.clj:7)
        at clojure.lang.RestFn.invoke(RestFn.java:397)
        at clojure.lang.Var.invoke(Var.java:375)
        at user$eval5.invokeStatic(form-init1433117969168569713.clj:1)
        at user$eval5.invoke(form-init1433117969168569713.clj:1)
        at clojure.lang.Compiler.eval(Compiler.java:6927)
        at clojure.lang.Compiler.eval(Compiler.java:6917)
        at clojure.lang.Compiler.load(Compiler.java:7379)
        ... 14 more

所以代码似乎一直运行到最后,但抛出了空指针异常。是什么原因造成的?另外,Clojure 的堆栈跟踪有什么问题?似乎该语言的创建者很懒惰,根本没有在 clojure 级别实现异常抽象。

【问题讨论】:

    标签: java exception clojure functional-programming


    【解决方案1】:

    问题在于您将 let 的主体包裹在额外的括号中,因此有效地 nilprintln 的结果被作为函数调用。删除括号,它会像预期的那样工作:

    (defn -main
      [& args]
      (let [keskiarvot (map #(/ (reduce + %) (count %)) (map vector lampo1 lampo2))] 
        (println keskiarvot)
        (let [positiiviset (filter pos? keskiarvot)]
          (println positiiviset)
          (let [posKeskiarvo (double (/ (reduce + positiiviset) (count positiiviset)))]
            (println posKeskiarvo)))))
    

    【讨论】:

    • 如果我需要/想要存储中间结果或使代码更清晰,嵌套这样的方法是好是坏?据我所知 def 会使 var 全局化,这不是故意的。我认为这比将所有内容链接在一起更容易理解,因为那些让绑定名称有点记录正在发生的事情。
    • 内联定义可以用于调试目的,但不适用于最终代码。但是你也可以只写:``` (let [x ... _ (println x) y ... _ (println y)] (+ x y) `` 以避免嵌套lets。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    相关资源
    最近更新 更多