我在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]
中的*
和下一个*
指的是什么?(@_[* - 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]
是指“数组中的最后一个元素”,@arr[* - 2]
就是指“数组中的倒数第二个元素”,以此类推。
* + 2
计算出序列中的下一个值,并且是一个闭包,接受一个参数并将其加上2。虽然我们实际上可以简单地使用范围 @_[* - 1] .. Inf
来获得正确的结果,但检查所有偶数会浪费时间,因此 * + 2
可以产生一个奇数序列。
first
子程序的闭包已经是一个突破点了。我不知道first
会采取闭包。现在代码看起来更容易理解了。 - Lars Malmsteen