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}) - 但这并不是真正的解决方案,因为它甚至不会给出(from-java-shallow Class {})所能提供的。

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
by

clojure.java.reflect是否符合你想要完成的任务?

在类及其字段中明显存在很多循环依赖。

by
我真的很想使用clojure.java.data及其转换逻辑。由于我不控制正在使用的类,所以如果c.j.d不会因java.lang.Class抛出异常,那就太棒了。从那里开始我就好了,我知道该怎么做。
0
by

我想问的问题可能是:

你认为(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)?

by
是的,这些说法都是正确的。所以我的基本要求是 `(j/from-java-deep Class {})` 不应该抛出异常。考虑我的解决方案,也许 `{:class java.lang.Class}` 对于这种情况来说并不糟糕。如果它有文档说明,用户可以检测到这种情况并做出他们认为正确的相应处理。在 `clojure.java.data` 中有一些其他情况下特殊情况处理,这将是最新的n+1个案例。
...