我使用 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)