【问题标题】:Access mutable java.util.List in Clojure在 Clojure 中访问可变的 java.util.List
【发布时间】:2020-09-15 17:17:17
【问题描述】:

我正在使用第 3 方 Java 库,其中一个库事件将 java.util.List 作为参数传递,Clojure 将其公开为 clojure.lang.APersistentVector。我遇到的问题是该库要求我改变该列表以实现我所追求的功能。但是,由于 Clojure 已将列表返回为 APersistentVector,因此所有可变方法都会抛出 UnsupportedOperationException。

是否可以强制 Clojure 使用 List 的可变 Java 实现而不是不可变的 Clojure 版本?

我很欣赏这非常不像 Clojure,但它是图书馆的工作方式,现在,我只想让事情正常工作。

谢谢,

保罗

【问题讨论】:

    标签: java list clojure mutable


    【解决方案1】:

    当您说“哪个 Clojure 公开为 clojure.lang.APersistentVector”时,您的意思并不清楚。如果 Clojure 调用的 Java 方法返回带有类 java.util.ArrayList 的对象 x,那么在 Clojure 中调用 (class x) 应该会显示 java.util.ArrayList。

    您正在使用的库中是否发生了一些转换代码,可能是用于 Java 方法调用的 Clojure 包装器,正在执行此转换?

    Clojure REPL 会话示例显示您确实可以获取 java.util.ArrayList 对象并在 Clojure 代码中改变它们:

    user=> (def mutlist1 (java.util.ArrayList. [1 2 3]))
    #'user/mutlist1
    user=> mutlist1
    [1 2 3]
    user=> (class mutlist1)
    java.util.ArrayList
    ;; add a new element -1 at index 1
    user=> (.add mutlist1 1 -1)
    nil
    user=> mutlist1
    [1 -1 2 3]
    

    【讨论】:

    • 谢谢,我想要实现的是一个类似这样的函数:github.com/ngs-doo/TemplaterExamples/blob/… 我已经使用 reify 来扩展接口,事件被连接到一个 java.util.List (它没有如果我使用 ArrayList,则不会被调用)。但是,提供的列表类是 clojure.lang.PersistentVector。我已经尝试过类型提示,这没什么区别,
    • 您是否在某个时候使用 Clojure 向量调用 API,然后 Java 库将其传回给您进行修改?因为 Clojure 持久序列数据结构确实实现了 java.util.List 接口(但不是变异方法,根据该接口的 Java API 文档,这些方法是可选的)。
    • 是的,它通过将 java.util.List 连接到接口实现 (github.com/ngs-doo/TemplaterExamples/blob/…) 来配置。然后它在 Clojure 数据结构中传递并执行,但是当调用该函数时,传递的列表是持久的,并且在尝试对其进行变异时会出错。
    • 也许我在这里想得太简单了,但是如果 你的 Clojure 代码正在调用你使用 reify 创建的这个对象,并且你的 Clojure 代码正在向它传递一个 Clojure 向量,那么这当然是不可变的。您应该更改调用该方法的代码,以将 java.util.List 接口的可变实现传递给它,例如 java.util.ArrayList。如果您有 Clojure 向量 v,您可以通过调用 (java.util.ArrayList.v) 创建这样的 ArrayList。如果这不是正在发生的事情,那么我不明白是谁在调用您的 reify 对象的方法并将其传递给 Clojure 向量
    • 谢谢,问题是我对 Java 互操作缺乏了解。
    猜你喜欢
    • 2013-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-07
    • 1970-01-01
    • 1970-01-01
    • 2021-09-16
    • 1970-01-01
    相关资源
    最近更新 更多