Clojure-带有基元数组的反射警告。长度
我在clojure中尝试在java浮点数组上使用实例方法时遇到了一些问题。具体而言,以下代码在调用Clojure-带有基元数组的反射警告。长度,clojure,primitive,Clojure,Primitive,我在clojure中尝试在java浮点数组上使用实例方法时遇到了一些问题。具体而言,以下代码在调用.length (defn make-matrix ([^floats fs] (let [len-fs (.length fs)] (cond (>= len-fs 16) (Matrix4. fs) (>= len-fs 9) (Matrix3. fs) :else (throw (IllegalArgumentExc
.length
(defn make-matrix
([^floats fs]
(let [len-fs (.length fs)]
(cond (>= len-fs 16) (Matrix4. fs)
(>= len-fs 9) (Matrix3. fs)
:else (throw (IllegalArgumentException. (str "Array must have at least 9 elements (found" len-fs ")")))))))
根据我的理解,类型提示应该消除了解析对
.length
的调用的反射需求。我遗漏了什么?JVM上的数组与常规对象不同,它们的长度不是通过字段查找获得的,而是通过专门的操作码数组长度
获得的。Java的array.length
符号就是编译成这个操作码的语法糖。因此,(.length fs)
将在运行时失败,因为fs
既没有length
方法,也没有length
字段(假设它实际上是一个数组)
因此,您应该使用clojure.core/alength
函数:
(alength fs)
如果没有类型提示,这将导致反射调用;有了类型提示,它将直接调用返回
fs.length
(用Java表示法)的静态方法。基本数组在JVM中是一种特殊情况,证明这一点的是有一条字节码指令用于获取它们的长度:。因此Clojure显示反射警告的原因是,浮点数组[F
的类没有声明名为length
的字段,因此当它尝试获取它()时,字段不在那里
您可以通过以下操作自己检查它:
(-> (float-array [1])
class
(.getField "length"))