Clojure:带递归的空指针异常
Clojure: nullpointerexception with recursion
我正在创建一个重载函数,它将数字列表作为参数(以及数字列表和重载签名中的单个数字)。必须从该列表中找到并返回最高值。我知道可用的 "sort" 方法可以自动为您对列表进行排序,但我试图使用递归来发现最高值。下面是我正在使用的代码。
32 (defn my-max
33 ([list]
34 (if (empty? list)
35 -1
36 (my-max (pop list) (first list))) ; recursive call
37 )
38 ([list high]
39 (if (empty? list) ; base case
40 high)
41 (if (> (first list) high)
42 (my-max (pop list) (first list)))
43 (my-max (pop list) high))
44 )
45
46 (println (my-max '(1 2 3)))
如您所见,我硬编码了一个包含 1、2 和 3 的列表,应该返回 3。当 运行 我收到错误代码时:
Exception in thread "main" java.lang.NullPointerException
at clojure.lang.Numbers.ops(Numbers.java:942)
at clojure.lang.Numbers.gt(Numbers.java:227)
at user$my_max.invoke(HelloWorld.clj:41)
at user$my_max.invoke(HelloWorld.clj:42)
at user$my_max.invoke(HelloWorld.clj:42)
at user$my_max.invoke(HelloWorld.clj:36)
at user$eval2.invoke(HelloWorld.clj:46)
at clojure.lang.Compiler.eval(Compiler.java:6619)
at clojure.lang.Compiler.load(Compiler.java:7064)
at clojure.lang.Compiler.loadFile(Compiler.java:7020)
at clojure.main$load_script.invoke(main.clj:294)
at clojure.main$script_opt.invoke(main.clj:356)
at clojure.main$main.doInvoke(main.clj:440)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.lang.Var.invoke(Var.java:415)
at clojure.lang.AFn.applyToHelper(AFn.java:161)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
此错误发生在最终的递归调用中,其中 3 已从列表中 "popped" 返回到 my-max,因为 "high" 列表为空并且:
(if (empty? list) ; line 39, base case
应该评估为真,但评估为假。你有关于这个问题的thoughts/solutions吗?
该语句(第 39-40 行)什么也没做。无论它的计算结果是什么(high
或 nil
),都不会使用该值。然后第 41 行求值,如果列表为空,(first list)
为 nil,因此空指针异常。
<
函数只能比较数字,所以一个非常简单的方法是使用 or
来确保它们是数字。第二个和第三个 if 语句的结尾 ) 也出现在错误的位置。
user> (defn my-max
([list]
(if (empty? list)
-1
(my-max (pop list) (first list))))
([list high]
(if (empty? list) ; base case
high
(if (> (or (first list) 0) (or high 0))
(my-max (pop list) (first list))
(my-max (pop list) high)))))
#'user/my-max
user> (println (my-max '(1 2 3)))
3
nil
我正在创建一个重载函数,它将数字列表作为参数(以及数字列表和重载签名中的单个数字)。必须从该列表中找到并返回最高值。我知道可用的 "sort" 方法可以自动为您对列表进行排序,但我试图使用递归来发现最高值。下面是我正在使用的代码。
32 (defn my-max
33 ([list]
34 (if (empty? list)
35 -1
36 (my-max (pop list) (first list))) ; recursive call
37 )
38 ([list high]
39 (if (empty? list) ; base case
40 high)
41 (if (> (first list) high)
42 (my-max (pop list) (first list)))
43 (my-max (pop list) high))
44 )
45
46 (println (my-max '(1 2 3)))
如您所见,我硬编码了一个包含 1、2 和 3 的列表,应该返回 3。当 运行 我收到错误代码时:
Exception in thread "main" java.lang.NullPointerException
at clojure.lang.Numbers.ops(Numbers.java:942)
at clojure.lang.Numbers.gt(Numbers.java:227)
at user$my_max.invoke(HelloWorld.clj:41)
at user$my_max.invoke(HelloWorld.clj:42)
at user$my_max.invoke(HelloWorld.clj:42)
at user$my_max.invoke(HelloWorld.clj:36)
at user$eval2.invoke(HelloWorld.clj:46)
at clojure.lang.Compiler.eval(Compiler.java:6619)
at clojure.lang.Compiler.load(Compiler.java:7064)
at clojure.lang.Compiler.loadFile(Compiler.java:7020)
at clojure.main$load_script.invoke(main.clj:294)
at clojure.main$script_opt.invoke(main.clj:356)
at clojure.main$main.doInvoke(main.clj:440)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.lang.Var.invoke(Var.java:415)
at clojure.lang.AFn.applyToHelper(AFn.java:161)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
此错误发生在最终的递归调用中,其中 3 已从列表中 "popped" 返回到 my-max,因为 "high" 列表为空并且:
(if (empty? list) ; line 39, base case
应该评估为真,但评估为假。你有关于这个问题的thoughts/solutions吗?
该语句(第 39-40 行)什么也没做。无论它的计算结果是什么(high
或 nil
),都不会使用该值。然后第 41 行求值,如果列表为空,(first list)
为 nil,因此空指针异常。
<
函数只能比较数字,所以一个非常简单的方法是使用 or
来确保它们是数字。第二个和第三个 if 语句的结尾 ) 也出现在错误的位置。
user> (defn my-max
([list]
(if (empty? list)
-1
(my-max (pop list) (first list))))
([list high]
(if (empty? list) ; base case
high
(if (> (or (first list) 0) (or high 0))
(my-max (pop list) (first list))
(my-max (pop list) high)))))
#'user/my-max
user> (println (my-max '(1 2 3)))
3
nil