我正在尝试使用 native Java 数组做一些事情,但我不明白这两个双数组实例化之间的区别。这与装箱和拆箱值有关吗?在所有情况下,每个数组的 (first...)
都具有 java.lang.Double 类型。 Clojure 协议(protocol)似乎对这种区别很敏感。
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
最佳答案
有两种不同类型的数组需要考虑:
[D
是一个原始 double 组,等价于Javadouble[]
[Ljava.lang.Double;
是Double
引用的数组,等价于Java的Double[]
.
(奇怪的表示法是因为这是这些类型在 Java 字节码中的内部表示……这在 Clojure 中公开有点奇怪,但您只需要忍受它)
因为它们是不同的类型,所以它们在 Clojure 协议(protocol)中的处理方式不同。
假设您坚持使用原始 double 运算并避免任何不必要的装箱,原始 double 组通常会提供更好的性能。您可以将原始数组视为未装箱值的数组,将引用数组视为装箱值的数组。
使用引用数组的主要原因是,如果您的值在您收到它们时已经装箱,和/或如果您打算将它们传递给需要装箱值的其他函数或集合。在这种情况下,将 double 拆箱然后再次装箱是低效的,因此将它们保留为装箱形式是明智的。
FWIW,有几个库可以轻松处理双数组。特别是你应该检查HipHip (专门的数组操作),core.matrix (支持多种类型的 vector/矩阵运算,包括 double 组)和 vectorz-clj (与 core.matrix 一起工作,将双数组包装为通用 vector )
关于java - Clojure:[D 和 [Ljava.lang.Double; 之间有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20727267/