我使用 Clojure 的 Java API,我有一个通过代码创建的持久向量:
IPersistentVector vec = PersistentVector.create();
后来填充了值。
我需要将此向量的内容提取为LazySeq
. 我知道向量的方法seq()
返回一个ISeq
. 有没有办法把它转换ISeq
成LazySeq
?
谢谢,
克里斯
我使用 Clojure 的 Java API,我有一个通过代码创建的持久向量:
IPersistentVector vec = PersistentVector.create();
后来填充了值。
我需要将此向量的内容提取为LazySeq
. 我知道向量的方法seq()
返回一个ISeq
. 有没有办法把它转换ISeq
成LazySeq
?
谢谢,
克里斯
ISeq
是 seqs 的接口,所以也LazySeq
实现ISeq
了。函数类型提示其seq
返回为ISeq
.
调用seq
向量将返回 a PersistentVector$ChunkedSeq
,这是一种不同类型的惰性序列。它的实现被分块以逐个元素地摊销生产它的成本(我认为它一次评估 8 个元素 iirc)。
如果你真的想要一个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);
一般来说,最好总是通过从运行时获得的 Var 调用 Clojure 类,并且只转换为接口,而不是具体类型。这大大降低了从发布到发布的过程中发生问题的机会。
我可以想到绝对没有充分的理由这样做和几个不好的理由,但这是较低的水平。
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)