在Clojure中打印原始数组

13

我正在REPL环境下,创建了一个Java数组:

=> (def arr (double-array [1 2 3]))
当然,如果我想查看我的arr,我会得到:
=> arr
#<double[] [D@2ce628d8>
有什么方法能够使Java原始类型的数组像Clojure的 persistentVector 一样打印输出吗?
=> arr
[1.0 2.0 3.0]

我知道我可以将我的数组封装在某种漂亮的打印函数中(这是我目前的做法),但有些情况下这很麻烦,例如向量是地图的一部分时:

=> my-map
{"1" #<double[] [D@47254e47>, "2" #<double[] [D@11d2625d>}
3个回答

19

像下面这么简单的代码行吗?

user=> (seq arr)
(1.0 2.0 3.0)

如果只是针对REPL的话,技术语义可能并不重要。

更新

事实证明,使用pretty print (pprint)与您的向量映射一起工作得很好:

user=> (def my-map {"1" (double-array [1 2 3])
                    "2" (double-array [1 2 3])})
#'user/my-map
user=> (pprint my-map)
{"1" [1.0, 2.0, 3.0], "2" [1.0, 2.0, 3.0]}

最终更新:从评论中的Google Groups讨论链接

提问者在以下的讨论中找到了一个他喜欢的答案:

> 是否有办法使Clojure repl默认情况下进行漂亮的打印?

尝试:

(clojure.main/repl :print pprint)

> 谢谢!这正是我所需要的。


谢谢,Scott。漂亮的打印在这里是解决问题的一半。另一半是:http://groups.google.com/group/clojure/browse_thread/thread/c9db56b8daeaffa2?fwc=1&pli=1 - charleslparker
1
哇,太酷了。我喜欢我们通过 Stack Overflow 一起发现新东西的感觉。团队合作,击掌庆祝! - Scott
@ScottLowe:请将其包含在您的答案中。将两个部分放在同一个地方也不会有什么坏处 :) - Goran Jovic

1

str函数只是调用Java对象的.toString方法,对于数组来说并不太方便。为了获得良好的表示(正如其他人所述)可以调用(java.util.Arrays/toString arr)。

然而,在普通的Clojure println和str代码中如何透明地实现呢?我们可以在Array上实现一个代理并替换.toString方法吗?或者我们应该使用str实现一个新的str2协议,除了Array类之外的所有内容都使用str?

我的猜测是代理arr将是最佳选择,因为即使从另一个名称空间调用,它也可以与调用其上的str的其他代码一起使用。不过我不知道如何在Array上实现代理 :)


1

总有一种Java互操作解决方案:

(java.util.Arrays/toString arr)

所以你会有

(map #(java.util.Arrays/toString (val %)) my-map)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接