我在RosettaCode遇到了这段代码
constant @primes = 2,3,{ first * %% none(@_),(@_[* - 1],* + 2 ... Inf) } ... Inf;
say @primes[^10];
在显式生成器块内:
1- @_
指的是什么序列?
2-第一个*
指的是什么?
3- *
中的@_[* - 1]
和下一个*
指的是什么?
4-序列(@_[* - 1],* + 2 ... Inf)
如何用于查找素数?
谢谢。
我在RosettaCode遇到了这段代码
constant @primes = 2,3,{ first * %% none(@_),(@_[* - 1],* + 2 ... Inf) } ... Inf;
say @primes[^10];
在显式生成器块内:
1- @_
指的是什么序列?
2-第一个*
指的是什么?
3- *
中的@_[* - 1]
和下一个*
指的是什么?
4-序列(@_[* - 1],* + 2 ... Inf)
如何用于查找素数?
谢谢。
外部序列运算符可以理解为:从2和3开始序列,然后运行块中的代码得出以下每个值,一直到无穷大。
序列运算符将根据需要传递尽可能多的参数。例如,斐波那契数列表示为1,1,* + * ... Inf
,其中* + *
是lambda -> $a,$b { $a + $b }
的简写;由于这需要两个参数,因此将在序列中为其指定前两个值。
当我们在一个块中使用@_
时,就好像我们写了一个-> *@_ { }
这样的lambda一样,这是一种s脚。与...
一起使用时,这意味着我们希望全部传递序列中的先前值。
子first
包含一个谓词(我们评估为返回true或false的谓词)和要搜索的值列表,并返回与该谓词匹配的第一个值。 (有关读取此类内容的提示:每当我们进行类似function-name arg1,arg2
的调用时,我们总是在解析参数的项,这意味着我们知道*
在这里不能是乘法运算符。)>
我们给first
的谓词是* %% none(@_)
。这是一个带一个参数的闭包,它检查该序列是否可被该序列中的所有先前值整除-因为如果是,则它不能是素数!
接下来的@_[* - 1],* + 2 ... Inf
是要搜索的值序列,直到找到下一个质数为止。它采用以下形式:第一个值,如何获取下一个值,并一直持续到无穷大。
第一个值是我们找到的最后一个质数。同样,* - 1
是一个接受参数并从中减去1的闭包。当我们将代码传递给数组索引器时,将使用元素数量来调用它。因此@arr[* - 1]
是“数组中倒数第二个”的Raku惯用语,@arr[* - 2]
将是“数组中倒数第二个”的等等。
* + 2
计算序列中的下一个值,它是一个闭包,接受一个参数并将其加2。尽管我们实际上可以做一个简单的范围@_[* - 1] .. Inf
并得到正确的结果,但是检查所有偶数是浪费的,因此* + 2
在那里产生一个奇数序列。
因此,直观地讲,这都意味着:下一个质数是之前的质数均不除的第一个(奇数)值。