gpt4 book ai didi

kotlin - Kotlin Coroutines 文档中的素数示例如何工作?

转载 作者:行者123 更新时间:2023-12-04 18:02:03 26 4
gpt4 key购买 nike

我正在浏览 Kotlin 的协程文档,并且在这个示例之前一直遵循得很好。我很难理解它在找到素数时是如何计算的,特别是 filter 的返回值如何。函数同时被返回并分配给 cur ,以及仍然从 numbersFrom 生成数字方法。

我添加了调试语句来尝试跟踪正在运行的各种协程,但我仍然迷失在它启动新协程并从其他人那里接收数字的逻辑流程上。

https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md#prime-numbers-with-pipeline

编码:

fun log(msg: String) = println("[${Thread.currentThread().name}] $msg")

fun main(args: Array<String>) = runBlocking<Unit> {
var cur = numbersFrom(context, 2)
for (i in 1..10) {
val prime = cur.receive()
println(prime)
cur = filter(context, cur, prime)
}
}

fun numbersFrom(context: CoroutineContext, start: Int) = produce<Int>(context) {
var x = start
while (true) {
log("NumbersFrom Send: ${x}")
send(x++)
} // infinite stream of integers from start
}

fun filter(context: CoroutineContext, numbers: ReceiveChannel<Int>, prime: Int) = produce<Int>(context) {
for (x in numbers) {
log("filter ${x}, prime ${prime}")
if (x % prime != 0) {
send(x)
}
}
}

输出:
[main @coroutine#2] NumbersFrom Send: 2
[main @coroutine#2] NumbersFrom Send: 3
2
[main @coroutine#3] filter 3, prime 2
[main @coroutine#2] NumbersFrom Send: 4
[main @coroutine#2] NumbersFrom Send: 5
3
[main @coroutine#3] filter 4, prime 2
[main @coroutine#3] filter 5, prime 2
[main @coroutine#4] filter 5, prime 3
[main @coroutine#2] NumbersFrom Send: 6
[main @coroutine#3] filter 6, prime 2
5
[main @coroutine#2] NumbersFrom Send: 7
[main @coroutine#2] NumbersFrom Send: 8
[main @coroutine#3] filter 7, prime 2
[main @coroutine#3] filter 8, prime 2
[main @coroutine#4] filter 7, prime 3
[main @coroutine#2] NumbersFrom Send: 9
[main @coroutine#2] NumbersFrom Send: 10
[main @coroutine#5] filter 7, prime 5
[main @coroutine#3] filter 9, prime 2
[main @coroutine#3] filter 10, prime 2
7
[main @coroutine#4] filter 9, prime 3
[main @coroutine#2] NumbersFrom Send: 11
[main @coroutine#2] NumbersFrom Send: 12
[main @coroutine#3] filter 11, prime 2
[main @coroutine#3] filter 12, prime 2
[main @coroutine#4] filter 11, prime 3
[main @coroutine#2] NumbersFrom Send: 13
[main @coroutine#2] NumbersFrom Send: 14
[main @coroutine#5] filter 11, prime 5
[main @coroutine#3] filter 13, prime 2
[main @coroutine#3] filter 14, prime 2
[main @coroutine#6] filter 11, prime 7
[main @coroutine#4] filter 13, prime 3
[main @coroutine#2] NumbersFrom Send: 15
[main @coroutine#2] NumbersFrom Send: 16
11
[main @coroutine#5] filter 13, prime 5
[main @coroutine#3] filter 15, prime 2
[main @coroutine#3] filter 16, prime 2
[main @coroutine#6] filter 13, prime 7
[main @coroutine#4] filter 15, prime 3
[main @coroutine#2] NumbersFrom Send: 17
[main @coroutine#2] NumbersFrom Send: 18
[main @coroutine#7] filter 13, prime 11
[main @coroutine#3] filter 17, prime 2
[main @coroutine#3] filter 18, prime 2
13
[main @coroutine#4] filter 17, prime 3
[main @coroutine#2] NumbersFrom Send: 19
[main @coroutine#2] NumbersFrom Send: 20
[main @coroutine#5] filter 17, prime 5
[main @coroutine#3] filter 19, prime 2
[main @coroutine#3] filter 20, prime 2
[main @coroutine#6] filter 17, prime 7
[main @coroutine#4] filter 19, prime 3
[main @coroutine#2] NumbersFrom Send: 21
[main @coroutine#2] NumbersFrom Send: 22
[main @coroutine#7] filter 17, prime 11
[main @coroutine#5] filter 19, prime 5
[main @coroutine#3] filter 21, prime 2
[main @coroutine#3] filter 22, prime 2
[main @coroutine#8] filter 17, prime 13
[main @coroutine#6] filter 19, prime 7
[main @coroutine#4] filter 21, prime 3
[main @coroutine#2] NumbersFrom Send: 23
[main @coroutine#2] NumbersFrom Send: 24
17
[main @coroutine#7] filter 19, prime 11
[main @coroutine#3] filter 23, prime 2
[main @coroutine#3] filter 24, prime 2
[main @coroutine#8] filter 19, prime 13
[main @coroutine#4] filter 23, prime 3
[main @coroutine#2] NumbersFrom Send: 25
[main @coroutine#2] NumbersFrom Send: 26
[main @coroutine#9] filter 19, prime 17
[main @coroutine#5] filter 23, prime 5
[main @coroutine#3] filter 25, prime 2
[main @coroutine#3] filter 26, prime 2
19
[main @coroutine#6] filter 23, prime 7
[main @coroutine#4] filter 25, prime 3
[main @coroutine#2] NumbersFrom Send: 27
[main @coroutine#2] NumbersFrom Send: 28
[main @coroutine#7] filter 23, prime 11
[main @coroutine#5] filter 25, prime 5
[main @coroutine#3] filter 27, prime 2
[main @coroutine#3] filter 28, prime 2
[main @coroutine#8] filter 23, prime 13
[main @coroutine#4] filter 27, prime 3
[main @coroutine#2] NumbersFrom Send: 29
[main @coroutine#2] NumbersFrom Send: 30
[main @coroutine#9] filter 23, prime 17
[main @coroutine#3] filter 29, prime 2
[main @coroutine#3] filter 30, prime 2
[main @coroutine#10] filter 23, prime 19
[main @coroutine#4] filter 29, prime 3
[main @coroutine#2] NumbersFrom Send: 31
[main @coroutine#2] NumbersFrom Send: 32
23
[main @coroutine#5] filter 29, prime 5
[main @coroutine#3] filter 31, prime 2
[main @coroutine#3] filter 32, prime 2
[main @coroutine#6] filter 29, prime 7
[main @coroutine#4] filter 31, prime 3
[main @coroutine#2] NumbersFrom Send: 33
[main @coroutine#2] NumbersFrom Send: 34
[main @coroutine#7] filter 29, prime 11
[main @coroutine#5] filter 31, prime 5
[main @coroutine#3] filter 33, prime 2
[main @coroutine#3] filter 34, prime 2
[main @coroutine#8] filter 29, prime 13
[main @coroutine#6] filter 31, prime 7
[main @coroutine#4] filter 33, prime 3
[main @coroutine#2] NumbersFrom Send: 35
[main @coroutine#2] NumbersFrom Send: 36
[main @coroutine#9] filter 29, prime 17
[main @coroutine#7] filter 31, prime 11
[main @coroutine#3] filter 35, prime 2
[main @coroutine#3] filter 36, prime 2
[main @coroutine#10] filter 29, prime 19
[main @coroutine#8] filter 31, prime 13
[main @coroutine#4] filter 35, prime 3
[main @coroutine#2] NumbersFrom Send: 37
[main @coroutine#2] NumbersFrom Send: 38
[main @coroutine#11] filter 29, prime 23
[main @coroutine#9] filter 31, prime 17
[main @coroutine#5] filter 35, prime 5
[main @coroutine#3] filter 37, prime 2
[main @coroutine#3] filter 38, prime 2
29
[main @coroutine#10] filter 31, prime 19
[main @coroutine#4] filter 37, prime 3
[main @coroutine#2] NumbersFrom Send: 39

最佳答案

该示例的重点是实现 Sieve of Eratosthenes .换句话说,通过过滤掉因可分而不能为素数的数来找到素数。剩下的都是素数。

让我们看看我们有什么。我将忽略所有 context变量,它只是让事情更容易谈论。

首先,我们有一个名为 numbersFrom 的函数。 ,这只是从 2 开始的无穷无尽的整数序列(在这种情况下)。

我们还有一个函数叫做 filter ,它接受一个 channel 和一个可能是素数的数字。查看返回类型,我们可以看到这个函数返回了一个新的生产者。为了产生结果(在这种情况下为 Int s),send可以调用函数。查看函数体,filter将接受 channel 外的数字(通过 send )并拒绝任何可以被质数整除的东西(不做任何事情)。

例如,如果 channel 产生 4 而素数是 2,则被拒绝。另一方面,如果 channel 产生 5 而素数是 2,它将 send那个号码。现在应该很明显 filter就像它的名字所说的那样 - 读取输入,找到它喜欢的,将它们发送到它的输出。

现在让我们看一下主要功能。首先,我们创建一个从 2 开始的数字流(多么巧合,第一个素数!)并将其分配给 cur .到现在为止还挺好。

接下来,我们开始一个循环。我将 10 减少到 3 以使事情更容易理解,但本质上这个数字意味着主要方法将计算多少个素数。如果您想要前 100 个素数,请将其设置为 100。

在循环中,我们通过调用 receive() 从数字列表中取出第一个数字。在 cur .这是一个暂停功能。正如我上面提到的,它将得到一个 2 作为它的第一个 prime值(value)。

现在这是有趣的部分。我们认为 2 , 并将其用作调用 filter 的基础,以及 cur ,当前是 Int 的流s,并将其重新分配给 cur .那是什么意思? cur现在代表一个整数流,过滤为不能被 2 整除!。

在下一个循环中,我们从 cur 中取出第一个数字。 channel ,它是一个 3. 下一个素数。为什么是3?因为filter(2)允许它通过 (3 % 2 != 0)。这是有趣的部分。现在我们获取 cur(一个过滤后的不能被 2 整除的数字列表)并将其传递给 filter函数,以及 3(我们最近的素数)。现在cur表示不能被 2 或 3 整除的数字流。看看这是怎么回事?

基本上在这一点上,我们有这个:

numbers -> filter(2) -> filter(3)

或者,阅读另一个(不太精确的 wrt 协程,但更容易想象):
filter(3, filter(2, numbers))

任何出现在 cur 开头的数字是素数,因为它通过了所有过滤器。

感谢您提出这个问题! “ Go learn Kotlin Coroutines”已经在我的研究 list 上几个星期了,我早上好,阅读了它们并弄清楚了这一点。

关于kotlin - Kotlin Coroutines 文档中的素数示例如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44395147/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com