选择列表生成表达式的语法

发布于 2024-08-08 08:00:42 字数 1431 浏览 6 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

久夏青 2024-08-15 08:00:42

还有 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 中看到这个时,我不得不想:“代价是什么?”

There's also Python's approach--no special syntax for generators; the presence of a "yield" statement is all it takes. Any statements that takes a block could be used, though I'd expect to find only loops used in practice:

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]

Here I'm assuming the right endpoint isn't included in a range.

To be completely honest, when I saw this in Python, I had to wonder: "at what cost?"

北音执念 2024-08-15 08:00:42

看看 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。

Check out what F# does. You can do

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

where seq-expr is a form that includes most language constructs along with 'yield'. So e.g. you can write

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

The F# compiler translates this code into a state machine implementation of IEnumerable (like C# does for iterator blocks).

I like this syntax because it means e.g. you can write the exact same code you would write to "do imperative stuff now", e.g.

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

but wrap that code in seq{} and use 'yield' and the code becomes a lazy IEnumerable instead.

汐鸠 2024-08-15 08:00:42
IEnumerable nats = 0...42

or for generators 

IEnumerable nats = yield 0...42
IEnumerable nats = 0...42

or for generators 

IEnumerable nats = yield 0...42
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文