2

我使用 Clojure 的 Java API,我有一个通过代码创建的持久向量:

 IPersistentVector vec = PersistentVector.create();

后来填充了值。

我需要将此向量的内容提取为LazySeq. 我知道向量的方法seq()返回一个ISeq. 有没有办法把它转换ISeqLazySeq?

谢谢,

克里斯

4

2 回答 2

2

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 类,并且只转换为接口,而不是具体类型。这大大降低了从发布到发布的过程中发生问题的机会。

于 2014-02-03T18:39:48.660 回答
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)
于 2014-02-03T19:06:01.217 回答