使用if定义函数时出错

时间:2011-10-08 20:26:35

标签: function clojure classcastexception

我们有一个简单的函数定义:

(defn calculate [d x y]
  ((if (and (== d 1) (== x 1) (== y 0))
     1
     0)))
(println (calculate 1 1 0))

但是这导致了这个错误:

Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke    (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    at jline.ConsoleRunner.main(ConsoleRunner.java:69)
Caused by: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn
    at user$calculate.invoke(main.clj:13)
    at user$eval5.invoke(main.clj:17)
    at clojure.lang.Compiler.eval(Compiler.java:6465)
    at clojure.lang.Compiler.load(Compiler.java:6902)
    at clojure.lang.Compiler.loadFile(Compiler.java:6863)
    at clojure.main$load_script.invoke(main.clj:282)
    at clojure.main$script_opt.invoke(main.clj:342)
    at clojure.main$main.doInvoke(main.clj:426)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.lang.Var.invoke(Var.java:401)
    at clojure.lang.AFn.applyToHelper(AFn.java:161)
    at clojure.lang.Var.applyTo(Var.java:518)
    at clojure.main.main(main.java:37)
    ... 5 more

(顺便说一句,第13行是ifand的行。

与矢量相同:

(defn calculate [vectorr]
  ((if (and (== (vectorr 0) 1) (== (vectorr 1) 1) (== (vectorr 2) 0))
     1
     0)))
(println (calculate [1 1 0]))

这导致:

Caused by: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn

......一样。

并附图:

(defn calculate [mapp]
  ((if (and (== (mapp :d) 1) (== (mapp :x) 1) (== (mapp :y) 0))
     1
     0)))
(println (calculate {:d 1 :x 1 :y 0}))

结果在同一条消息中:

Caused by: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn

我们认为与if或比较有关。我们尝试使用普通参数,矢量作为参数,并使用地图,显然,错误保持不变。

我们还尝试了许多其他变体而没有对实际问题有更深入的了解。

2 个答案:

答案 0 :(得分:6)

你的函数体周围有一对额外的括号,这意味着你想要调用if的结果(它是1或0 - 即长)。

应该是:

(defn calculate [vectorr]
  (if (and (== (vectorr 0) 1) (== (vectorr 1) 1) (== (vectorr 2) 0))
     1
     0))

答案 1 :(得分:-1)

额外的括号会导致程序崩溃,因为它们会更改表达式的返回类型。通过将某些内容括在括号中,在clojure中,您最终将表达式包装为函数。然后,引用该函数输出的程序现在实际上引用了函数本身。

我发现,90%的时间,如果我在clojure中得到一个类强制转换异常,那是因为我在事故中创建了一个cloSure。