以下是用于与byte
一起使用的循环/重复结构的简化示例。
(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
绑定期望的内容与recur
对第一个参数的调用之间的类型不匹配。他们似乎都是byte
,所以我不知道问题是什么。
user=> (type (byte 0))
java.lang.Byte
user=> (type (first (map byte '(1 2 3))))
java.lang.Byte
答案 0 :(得分:2)
我在Clojure IRC频道上询问了这个问题,用户合作和dbasch帮助了我。我对该对话的理解如下。
似乎问题是last-byte
绑定中loop
的绑定是Java原语byte
,而(first bytez)
实际上返回java.lang.Byte
,源自java.lang.Object
。因此,在byte
的调用中传递的预期java.lang.Byte
Java原语与Object
(从recur
派生)之间存在类型不匹配:因此错误信息。
解决方法是将recur
参数转换为基元:(byte (first bytez))
。
另一种选择是使用byte-array
并使用aget
进行访问。
一般来说,了解您正在使用的类型非常重要,请记住原语和盒装类型不一定是可以互换的。似乎Clojure函数通常(永远不会)返回Java原语。