选择列表生成表达式的语法[关闭]
题
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
不隶属于 StackOverflow