我使用Clojure的Java API,我有一个通过代码创建的持久向量:
IPersistentVector vec = PersistentVector.create();
后来填充了值。
我需要将此向量的内容提取为LazySeq
。我知道向量的方法seq()
会返回ISeq
。有没有办法将此ISeq
转换为LazySeq
?
谢谢,
克里斯
答案 0 :(得分:2)
ISeq
是seqs的接口,因此LazySeq
也会实现ISeq
。 seq
函数类型将其返回提示为ISeq
。
在向量上调用seq
将返回PersistentVector$ChunkedSeq
,这是一种不同类型的延迟序列。它的实现是为了逐元素地分摊生产它的成本(我认为它一次评估8个元素)。
如果你真的想要LazySeq
,你可以做
(lazy-cat [1 2 3])
但这只会强制逐个元素评估并消除分块行为。
在Java中,这将是:
// once
Var lazyCat = RT.var("clojure.core", "lazy-cat");
// at use
IPersistentVector vector = ...
ISeq lv = (ISeq) lazyCat.invoke(vector);
请注意,它会让我实际将结果转换为LazySeq
,因此我在这里使用了接口ISeq
。 没有保证具体类LazySeq
是您将来在任何时候实际收到的内容。鉴于此,您可以直接调用seq:
// once
Var seq = RT.var("clojure.core", "seq");
// at use
IPersistentVector vector = ...
ISeq lv = (ISeq) seq.invoke(vector);
通常,总是通过从运行时获取的Vars调用Clojure类并且仅转换为接口,而不是转换为具体类型。这大大降低了从发布到发布的事情将会破坏的可能性。
答案 1 :(得分:1)
我完全没有理由去做这个以及几个不好的事情,但这里是较低的等级。
import clojure.lang.*;
public class Foo {
public static IFn thunk(final Object x){
return new AFn(){
public Object invoke() { return x; }
};
}
public static void main(String[] args) throws Exception {
PersistentVector vec;
LazySeq lazySeq;
vec = PersistentVector.create(1, 2, 3);
System.out.println(vec);
lazySeq = new LazySeq(thunk(vec));
System.out.println(lazySeq);
System.out.println(RT.printString(lazySeq));
}
}
输出,例如
[1 2 3]
clojure.lang.LazySeq@7861
(1 2 3)