我在 RosettaCode 遇到了这个代码
constant @primes = 2, 3, { first * %% none(@_), (@_[* - 1], * + 2 ... Inf) } ... Inf;
say @primes[^10];
在显式生成器块中:
1-
@_
执行什么或哪个序列s 指的是?2- 第一个
*
是做什么的引用?3- 做什么
*
在 @_[* - 1]
和下一个 *
引用?4- 序列如何
(@_[* - 1], * + 2 ... Inf)
服务于寻找素数的目的?谢谢你。
最佳答案
外层序列运算符可以理解为:以2和3开始序列,然后运行块中的代码,计算出以下每个值,并一直持续到无穷大。
序列运算符将传递该块所需的尽可能多的参数。例如,斐波那契数列表示为 1, 1, * + * ... Inf
,其中 * + *
是 lambda -> $a, $b { $a + $b }
的简写;由于这需要两个参数,因此它将被赋予序列中的前两个值。
当我们使用 @_
在一个块中,就好像我们写了一个 lambda 似的 -> *@_ { }
,这是一个slurpy。与 ...
一起使用时,这意味着我们希望传递序列中所有先前的值。
子first
接受一个谓词(我们评估返回 true 或 false 的东西)和要搜索的值列表,并返回与谓词匹配的第一个值。 (阅读此类内容的提示:每当我们执行类似 function-name arg1, arg2
的调用时,我们总是在解析参数的术语,这意味着我们知道 *
在这里不能是乘法运算符。)
我们给 first
的谓词是 * %% none(@_)
.这是一个闭包,它接受一个参数并检查它是否可以被序列中的任何先前值整除 - 因为如果是,它就不可能是素数!
接下来,@_[* - 1], * + 2 ... Inf
, 是要搜索的值序列,直到找到下一个素数。这采用以下形式:第一个值,如何获得下一个值,并一直持续到无穷大。
第一个值是我们找到的最后一个素数。再次,* - 1
是一个接受一个参数并从中减去 1 的闭包。当我们将代码传递给数组索引器时,它会使用元素数进行调用。因此@arr[* - 1]
是“数组中的最后一件事”的 Raku 成语,@arr[* - 2]
将是“数组中倒数第二个东西”等。* + 2
计算序列中的下一个值,它是一个闭包,它接受一个参数并将其加 2。虽然我们实际上可以做一个简单的范围 @_[* - 1] .. Inf
并得到正确的结果,检查所有偶数是浪费的,因此* + 2
是否有产生奇数序列。
所以,直觉上,这一切都意味着:下一个素数是前一个素数都没有分成的第一个(奇数)值。
关于sequence - Raku中素数计算代码的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58841508/