" clojure.lang.ArraySeq无法转换为clojure.lang.IFn"宏

时间:2015-05-06 20:12:47

标签: clojure macros

以下是代码:

(defmacro cond2 [& body]
  (when body
    `(if ~(first body)
       ~(if (next body)
          (second body)
          (throw (IllegalArgumentException. "error")))
       ~(cond2 (next (next (body)))))))
(cond2 (> 2 1) (println "2 > 1")
       :else   (println "2 <= 1"))

我收到了这个错误:

CompilerException java.lang.ClassCastException: clojure.lang.ArraySeq cannot be cast to clojure.lang.IFn, compiling:(/Users/personal_config_bin_files/workspace/cina/src/cina/ref_types.clj:1:24) 

如果删除递归部分,则错误消失:

(defmacro cond2 [& body]
  (when body
    `(if ~(first body)
       ~(if (next body)
          (second body)
          (throw (IllegalArgumentException. "error")))
       )))

这当然适用于有两个条款的身体。

如果我引用这样的递归部分:

(defmacro cond2 [& body]
  (when body
    `(if ~(first body)
       ~(if (next body)
          (second body)
          (throw (IllegalArgumentException. "error")))
       `(cond2 ~(next (next body))))))

然后我得到一个不同的错误:

CompilerException java.lang.RuntimeException: No such var: cina.ref-types/body, compiling:(/Users/personal_config_bin_files/workspace/cina/src/cina/ref_types.clj:331:5) 

使用cons代替语法引用有效:

(defmacro cond2 [& body]
  (when body
    `(if ~(first body)
       ~(if (next body)
          (second body)
          (throw (IllegalArgumentException. "error")))
       ~(cons 'cond2 (next (next body))))))
(cond2 (> 2 3) (println "good")
       :else   (println "bad"))

但我不知道区别是什么。谁能解释一下?

2 个答案:

答案 0 :(得分:1)

这是我需要的非引用拼接:

(defmacro cond2 [& body]
  (when body
    `(if ~(first body)
       ~(if (next body)
          (second body)
          (throw (IllegalArgumentException. "error")))
       (cond2 ~@(next (next body))))))

答案 1 :(得分:0)

问题是原始递归部分中的let annotation: MKAnnotation = mapView.annotations[0] as! MKAnnotation annotation.subtitle = nil - 它试图将(body)作为函数调用,然后抱怨它无法将seq转换为函数。

改为body,它应该可以正常工作。