我试图在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 (IllegalArgumentException. (str "Array must have at least 9 elements (found" len-fs ")")))))))根据我的理解,类型提示应该不需要反射来解析对.length的调用。我遗漏了什么?
发布于 2013-12-12 06:24:20
JVM上的数组与常规对象不太一样,它们的长度不是通过字段查找获得的,而是通过专门的操作代码arraylength获得的。Java的array.length表示法只是编译到这个操作码的语法糖。因此,(.length fs)将在运行时简单地失败,因为将发现fs既没有length方法,也没有length字段(假设它实际上是数组)。
因此,您应该使用clojure.core/alength函数:
(alength fs)如果没有类型提示,这将导致一个反射调用;使用类型提示,它将直接调用返回fs.length的静态方法(在Java中)。
发布于 2013-12-12 06:24:37
基元数组是JVM中的一个特殊情况,这证明了有一个字节码指令来获取它们的长度:[医]芳纶。因此,Clojure显示反射警告的原因是,用于floats [F数组的类没有声明一个名为length的字段,因此当它试图获取它(这里)时,该字段并不存在。
您可以自己检查它,执行以下操作:
(-> (float-array [1])
class
(.getField "length"))https://stackoverflow.com/questions/20535659
复制相似问题