Ceylon 为什么要在锡兰创建Iterable而不是序列?

Ceylon 为什么要在锡兰创建Iterable而不是序列?,ceylon,Ceylon,我已经读过了,但我真的不明白为什么有一种方法可以同时定义一个literable和一个literal序列 {String+} iterable = {"String1", "String2"}; [String+] sequence = ["String1", "String2"]; 由于Sequence是Iterable的一个子类型,它似乎应该能够完成Iterable所做的一切,甚至更多 那么有什么必要使用Iterable花括号初始值设定项呢?什么时候要使用它而不是方括号序列版本?流是惰性的

我已经读过了,但我真的不明白为什么有一种方法可以同时定义一个literable和一个literal序列

{String+} iterable = {"String1", "String2"};
[String+] sequence = ["String1", "String2"];
由于Sequence是Iterable的一个子类型,它似乎应该能够完成Iterable所做的一切,甚至更多

那么有什么必要使用Iterable花括号初始值设定项呢?什么时候要使用它而不是方括号序列版本?

流是惰性的

import ceylon.math.float {random}

value rng = {random()}.cycled;
这是一个懒惰的,无限的随机数流。构造流时不会调用函数
random
。另一方面,一个序列会急切地评估它的参数,在这种情况下,给你一次又一次调用
random
的结果。另一个例子:

function prepend<Element>(Element first, {Element*} rest) => {first, *rest};
value stream = { random() }.cycled
        .filter((x) => x>0.5)
        .map((x) => (x*100).integer);
printAll(stream.take(1000));
函数前置(元素第一,{Element*}rest)=>{first,*rest};

这里,流
rest
分布在结果流上,但仅在需要时进行。

正是@gdejohn所说的,但我想指出,如果要对流应用多个操作,那么惰性对性能尤其重要,例如:

function prepend<Element>(Element first, {Element*} rest) => {first, *rest};
value stream = { random() }.cycled
        .filter((x) => x>0.5)
        .map((x) => (x*100).integer);
printAll(stream.take(1000));

在这里,我们避免具体化长度为1000的整个序列,因为每个中间操作:
循环
过滤器()
映射()
,和
获取()
都返回一个流。即使是
printAll()
也不需要具体化一个序列。

除了
random()
东西被多次调用(直到现在我才意识到)之外,
[…]
也同样适用,不是吗<代码>[5]。循环的仍将返回一个懒惰的iterable。是,
[5]。循环的
是懒惰的。它不试图具体化一个无限序列:-)