Python 生成器在 Kotlin 中的等价物是什么?

Dj *_*shi 2 python yield generator sequence kotlin

如果我有一个 python 生成器函数,我们就说这个:

def gen():
    x = 0
    while (true):
        yield x
        x += 1
Run Code Online (Sandbox Code Playgroud)

该函数会记住其当前状态,每次调用时gen()都会产生一个新值。本质上,我想要一个能够记住其状态的 Kotlin 序列。

Sla*_*law 5

def gen():
    x = 0
    while (true):
        yield x
        x += 1 
Run Code Online (Sandbox Code Playgroud)

该函数会记住其当前状态,每次调用时gen()都会产生一个新值。

这是不正确的。每次调用时,gen()您都会获得一个新的“生成器对象”,其状态独立于该函数创建的任何其他生成器对象。然后,您查询生成器对象以获取下一个数字。例如:

def demo():
    numbers = gen()  # 'gen()' from your question
    for _ in range(0, 3):
        next_number = next(numbers)
        print(next_number)


if __name__ == '__main__'
    demo()
    print()
    demo()
Run Code Online (Sandbox Code Playgroud)

输出:

0
1
2

0
1
2
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,当您再次调用时,数字序列“重新开始” gen()(尽管如果您保留对旧生成器对象的引用,即使在gen()再次调用之后,它也会从 2 继续)。

在 Kotlin 中,您可以使用kotlin.sequences.iterator函数。它创建一个Iterator延迟生成下一个值的对象,就像 Python 生成器对象一样。例如:

fun gen() = iterator {
    var x = 0
    while (true) {
        yield(x)
        x++
    }
}

fun demo() {
    val numbers = gen()
    repeat(3) {
        val nextNumber = numbers.next()
        println(nextNumber)
    }
}

fun main() {
    demo()
    println()
    demo()
}
Run Code Online (Sandbox Code Playgroud)

这将输出:

0
1
2

0
1
2
Run Code Online (Sandbox Code Playgroud)

就像 Python 代码一样。

请注意,您可以使用 Kotlin 执行基本相同的操作,如果您想像 Python 生成器对象一样使用它,则Sequence只需将其转换Sequence为 an即可。Iterator但请记住,Kotlin 序列更多地用于定义一系列操作,然后一次延迟处理一组元素(有点像 Java 流,如果您熟悉它们)。