相关疑难解决方法(0)

Ruby相当于C#的'yield'关键字,或者,在没有预先分配内存的情况下创建序列

在C#中,你可以这样做:

public IEnumerable<T> GetItems<T>()
{
    for (int i=0; i<10000000; i++) {
        yield return i;
    }
}
Run Code Online (Sandbox Code Playgroud)

这将返回一个包含1000万个整数的可枚举序列,而无需在该长度的内存中分配集合.

有没有办法在Ruby中做同等的事情?我试图处理的具体例子是将矩形数组展平为要枚举的值序列.返回值不必是Array或者Set,而是某种只能按顺序迭代/枚举的序列,而不是索引.因此,不需要在存储器中同时分配整个序列.在.NET中,这是IEnumerableIEnumerable<T>.

关于Ruby世界中使用的术语的任何澄清都会有所帮助,因为我对.NET术语更熟悉.

编辑

也许我原来的问题还不够清楚 - 我认为yield在C#和Ruby 中具有非常不同含义的事实是造成混淆的原因.

我不想要一个需要我的方法来使用块的解决方案.我想要一个具有实际返回值的解决方案.返回值允许方便地处理序列(过滤,投影,连接,压缩等).

这是一个我可能会如何使用的简单示例get_items:

things = obj.get_items.select { |i| !i.thing.nil? }.map { |i| i.thing }
Run Code Online (Sandbox Code Playgroud)

在C#中,任何返回IEnumerable使用a的方法yield return都会导致编译器在幕后生成满足此行为的有限状态机.我怀疑使用Ruby的延续可以实现类似的东西,但我还没有看到一个例子,我自己也不清楚如何做到这一点.

我确实有可能用它Enumerable来实现这一目标.一个简单的解决方案是我们Array(包括模块Enumerable),但我不想在内存中创建一个包含N个项目的中间集合,只要它们可以懒得提供它们并且完全避免任何内存峰值.

如果这仍然没有意义,那么请考虑上面的代码示例. get_items返回一个枚举,在其select上调用.传递给的select是一个知道如何在需要时提供序列中的下一个项目的实例.重要的是,尚未计算整个项目集.只有当select需要一个项目时它才会要求它,并且潜在的代码get_items将开始行动并提供它.这种懒惰带有链条,这样select只有在map询问它时才从序列中抽取下一个项目.这样,可以一次对一个数据项执行长链操作.实际上,以这种方式构造的代码甚至可以处理无限 …

ruby yield sequences

7
推荐指数
2
解决办法
1198
查看次数

标签 统计

ruby ×1

sequences ×1

yield ×1