C#具有生成器函数,其语法如下:

IEnumerable<int> GetNats(int max)
{
   for (int i=0; i < max; ++i)
      yield return i;
}

我对编程语言感兴趣的功能(类似于Java,Scala,ActionScript和C#的简单面向对象编程)是生成器表达式。这些基本上是发电机功能的语法糖。

我目前最喜欢的候选人是以下语法:

IEnumerable<int> nats = 
  witheach (i in range(0, 42)) 
     yield i * 2; 

表达式 range(0,42)是一个内置的生成器函数。

所以我的问题是你希望在C#/ Java / Scala / ActionScript类型语言中看到生成器表达式的语法,为什么?

可能影响响应的一些因素是像Scala和ActionScript一样,我的语言中的类型是在类型之后声明的。例如:

var myVar : SomeType = initialValue;

匿名函数也是这样的:

var myFunc = function(int x) { 
  return x + 1; 
}

除此之外,我的其他语言语法类似于Java或C#。我的语言有一个 foreach 语句,它与C#非常相似。

有帮助吗?

解决方案

还有 Python的方法 - 没有针对生成器的特殊语法;存在“产量”。声明就是一切。可以使用任何带有块的语句,但我希望在实践中只找到使用的循环:

IEnumerable<int> nats = 
    for (i in range(0,42))
        yield i*2

String phrase = "I want to buy some cheese.";
IEnumerable<int> substrs =
    for (i in 0 .. phrase.length)
        for (j in i .. phrase.length+1)
            yield phrase[i..j]

这里我假设右端点不包含在范围内。

说实话,当我在Python中看到这个时,我不得不怀疑:“以什么代价?”

其他提示

查看F#的作用。你可以做到

seq { seq-expr }    // IEnumerable<T>, a.k.a. seq<T>
[ seq-expr ]        // list<T>
[| seq-expr |]      // array<T>

其中seq-expr是一个包含大多数语言结构和“yield”的表单。所以例如你可以写

seq {
    for i in 0..9 do
        for j in someColl do
            if i <> j then
                yield i*j
}

F#编译器将此代码转换为IEnumerable的状态机实现(就像迭代器块的C#一样)。

我喜欢这种语法,因为它意味着例如你可以编写完全相同的代码来编写“现在做必要的东西”,例如

    for i in 0..9 do
        for j in someColl do
            if i <> j then
                printfn "%d" i*j

但是将该代码包装在seq {}中并使用'yield',代码变成了懒惰的IEnumerable。

IEnumerable nats = 0...42

or for generators 

IEnumerable nats = yield 0...42
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top