如何实施Clojure ISEQ Injava



我想传递给java函数的地图。这些功能使用Java匿名类实现IFN接口。我还需要实现ISEQ接口以传递列表。ISEQ接口很简单,但没有文档。我需要知道ISEQ中的每种方法和/或找到实现所有ISEQ方法的类的Java代码(我不想将我的列表复制到Clojure结构(。

我需要知道ISEQ中的每种方法

您还应该了解它扩展的接口:

public interface Seqable {
    ISeq seq(); // returns an ISeq instance
}
public interface IPersistentCollection extends Seqable {
    // returns the count of this coll
    int count();
    // returns a new coll with o cons'd onto it
    IPersistentCollection cons(Object o);
    // returns a new empty coll (of same type?)
    IPersistentCollection empty();
    // compares this coll against o for equality
    boolean equiv(Object o);
}
public interface ISeq extends IPersistentCollection {
    // returns the first item in this seq
    Object first();
    // returns a new seq of every item in this except the first
    ISeq next();
    // returns a new seq of every item in this except the first
    // ASeq returns empty for empty
    ISeq more();
    // returns a new seq with o cons'd onto this seq
    ISeq cons(Object o);
}

...或找到实现所有ISEQ方法的类的Java代码

ASeq抽象类实施(大多数(ISeq。扩展ASeq实现ISeq.next()的类。

除了重新实现ISeq外,还可以更简单地完成目标。也许查看Clojure的Java实现会给您一些想法。

问题文本的这个片段似乎表明在数组上调用 seq,这是链接的答案对将Java数组转换为Clojure Seqs建议的问题,复制了内容的内容。阵列到新鲜的seq:

(我不想将我的列表复制到Clojure结构(

这是不是。相反,发生的是seq返回由数组备份的包装器SEQ,如以下替补交互所证明:

Clojure 1.9.0
user=> (def xs (object-array [:foo :bar]))
#'user/xs
user=> (seq xs)
(:foo :bar)
user=> (def s1 (doall (seq xs)))
#'user/s1
user=> s1
(:foo :bar)
user=> (aset xs 0 :quux)
:quux
user=> (seq xs)
(:quux :bar)
user=> s1
(:quux :bar)

请注意,突变基础阵列会导致对突变之前创建的阵列的SEQ的可观察变化。

这与seq的行为形成对比,当时通过java.util.List并非同时是ISeq,在这种情况下,确实会分配新的SEQ:

Clojure 1.9.0
user=> (def ys (java.util.ArrayList. [:foo :bar]))
#'user/ys
user=> ys
[:foo :bar]
user=> (def s2 (seq ys))
#'user/s2
user=> s2
(:foo :bar)
user=> (.set ys 0 :quux)
:foo
user=> ys
[:quux :bar]
user=> s2
(:foo :bar)

这不必是一个可怕的结果,因为SEQ会分解,但是避免任何包装可能是有意义的。

即使如此,还应检查确切的用法模式,因为可以将Java列表完全传递给Clojure并进行处理,而无需任何中间SEQ分配。例如,Iterable S可以直接有效地为reduce'D,而没有此类分配。

因此,我将重新检查以下假设:需要从Java侧传输到Clojure的列表需要作为ISeq实例跨越鸿沟。这并不是说在任何情况下都没有任何安排是有道理的 - 仅仅是从问题文本中提供的有限细节来看,在这种特殊情况下这是必要的。

至于如何实施ISeq,如果您决定最终这样做,我同意泰勒·伍德(Taylor Wood(的建议来检查clojure.lang.ASeq

最新更新