2024年Clojure的现状调查!中分享你的想法。

欢迎!请参阅关于页面了解更多关于如何使用本站的信息。

0
java.data

(clojure.java.data/from-java-deep Class {:}) 抛出 StackOverflowError

文档没有提及这一点,但我希望 java.data 能够处理这个案例。

您可以在 https://github.com/henrik42/java.data-with-Class/tree/master 中找到一个简短的例子。

这显示了错误。

clj -X main/this-call-throws
Execution error (StackOverflowError) at clojure.java.data/add-deep-getter-fn (data.clj:121).

作为一个临时的解决方案,我使用了 (defmethod j/from-java-deep Class [clazz _] {:class clazz}) -- 但这并不是一个真正的解决方案,因为它甚至不能提供与其他方式相同的结果。

clj -X main/this-call-works
(j/from-java-deep Class) ;=>  {:class java.lang.Class}

使用

(defmethod j/from-java-deep Class [clazz _] (j/from-java-shallow Class {}))

代替也没有好多少,因为它也不是深拷贝。

3 个答案

0

被选中
 
最佳答案

https://clojure.atlassian.net/browse/JDATA-23 -- 我可能这个月无法解决它,但的确需要一些分析。

0

clojure.java.reflect 是否更适合您想要做的任务?

类及其字段明显存在许多循环。

我真的很想使用 clojure.java.data 和它的转换逻辑。由于我无法控制所使用的类,如果 c.j.d 对 java.lang.Class 执行不抛出异常,那就太好了。从那里开始,我就没问题了,知道该做什么。
0

我认为我的问题应该是

您认为 (j/from-java-deep Class {}) 应该生成什么?

当您执行 (j/from-java-shallow Class {}) 时,可以看到许多类型为 Class 数组的属性,所以如果您尝试从 Java 到 Clojure 的“转换”,您会得到递归 -- 在 Class 的情况下,这种递归没有“底部”。

为了防止 from-java-deep 在这里崩溃,需要有一种“底部”来结束这种递归。要么是一个任意的深度,要么跟踪您见过的所有 Java 对象,并在树向下扩展时不再扩展相同的对象(假设这个检查足以创建一个“底部”)。但紧接着还有关于 from-java-deep 在这种情况下应该做什么的问题:对于那个子树返回 nil,返回某个其他信号值,返回 Java 对象本身,抛出不同的异常(指示哪个getter扩展失败,这样您可以重试并告诉它不要扩展那个getter)?

是的,这是真的。因此我的最小需求是 `(j/from-java-deep Class {})` 不应抛出异常。关于我的替代方案,可能`{:class java.lang.Class}`对于这种情况来说不是那么糟糕的结果。如果这一情况被记录下来,用户可以发现这种情况并根据他们的使用情况做出适当处理。在 `clojure.java.data` 中还有一些其他案例接受特殊处理,这将是一个第n+1次特殊处理。
...