下面是一个循环/递归构造的简化示例,旨在与字节
一起使用。
(defn test-lr []
(loop [last-byte (byte 0)
bytez (map byte '(1 2 3 4))
answer '()]
(if (empty? bytez)
answer
(recur (first bytez)
(rest bytez)
(cons (bit-or (first bytez last-byte) answer))))))
每当我尝试在 REPL 中编译此代码时,都会收到以下错误。
CompilerException java.lang.IllegalArgumentException:
recur arg for primitive local: last_byte is not matching primitive,
had: Object, needed: byte, compiling:...
该错误表明 loop
绑定(bind)所期望的内容与对 recur
的调用及其第一个参数提供的内容之间存在类型不匹配。它们似乎都是字节,所以我不明白问题是什么。
user=> (type (byte 0))
java.lang.Byte
user=> (type (first (map byte '(1 2 3))))
java.lang.Byte
最佳答案
我在 Clojure IRC channel 上询问了这个问题,用户 amalloy 和 dbasch 帮助了我。我从那次谈话中得到的理解如下。
问题似乎在于 loop
绑定(bind)中 last-byte
的绑定(bind)是 Java 原语 byte
,而 (first bytez)
实际上返回一个 java.lang.Byte
,它派生自 java.lang.Object
。因此,预期的 byte
Java 原语和 java.lang.Byte
(派生自 Object
)之间存在类型不匹配。在对 recur
的调用中传递:因此出现错误消息。
解决方法是将 recur
参数转换为原语:(byte (first bytez))
。
另一种选择是使用字节数组
并使用aget
进行访问。
一般来说,了解您正在使用的类型很重要,并记住基元和装箱类型不一定可以互换。 Clojure 函数似乎也通常(永远?)不返回 Java 原语。
关于Clojure:Clojure 重复中的 llegalArgumentException - 类型不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26198603/