Clojure:[D和[Ljava.lang.Double ;?]之间有什么区别?

时间:2013-12-22 07:33:09

标签: java clojure

我正在尝试使用本机Java数组做一些事情,而我不明白两个双数组实例之间的区别。这与拳击和取消装箱值有关吗?在所有情况下,每个数组的(first...)都有类型java.lang.Double。 Clojure协议似乎对这种区别很敏感。

user> (class (make-array Double/TYPE 3))  ;; [D
user> (class (double-array [1 2 3]))      ;; [D
user> (class (into-array (make-array Double/TYPE 3)))  ;; [Ljava.lang.Double;
user> (class (into-array (double-array [1 2 3])))      ;; [Ljava.lang.Double;
user> (class (into-array (repeat 2 (double-array [1 2 3]) ))) ;; [[D

3 个答案:

答案 0 :(得分:8)

要考虑两种不同类型的数组:

  • [D是一个原始双数组,相当于Java double[]
  • [Ljava.lang.Double;Double 引用的数组,相当于Java Double[]

(奇怪的符号是因为这是Java字节码中这些类型的内部表示...这在Clojure中暴露出来有点奇怪,但你只需要忍受它)

因为这些是不同的类型,所以使用Clojure协议对它们进行不同的处理。

原始双数组通常提供更好的性能,假设您坚持原始的双重操作并避免任何不必要的装箱。您可以将原始数组视为未装箱值的数组,将参考数组视为装箱值数组。

使用参考数组的主要原因是,如果您的值在收到时已经装箱,并且/或者您打算将它们传递给需要装箱值的其他功能或集合。在这种情况下,打开双打并将其再次打包是低效的,因此将它们保留为盒装形式是明智的。

FWIW,有几个库可以轻松地使用双数组。特别是你应该检查HipHip(专门的数组操作),core.matrix(支持包括双数组在内的许多类型上的向量/矩阵运算)和vectorz-clj(与core.matrix一起使用,包装为double)数组作为通用向量)

答案 1 :(得分:1)

双阵列未装箱。当您从数组中访问某个项目时,Clojure会自动将其打包,除非您使用期望该类型的类型提示函数访问它。

答案 2 :(得分:1)

您可以在此处获得JVM签名的说明:http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3