Raku 中的匿名状态变量与主题变量

Lar*_*een 8 raku

2020 年 1 月我写了这段代码

\n
my @a = ( 1, { ([+] 1 .. ++$ ) / [\xc3\x97] 1 .. ++$ } ... Inf)[^7];\nsay @a.join(\' + \') ~ "=" ~ [+] @a;\n
Run Code Online (Sandbox Code Playgroud)\n

用 Raku 表达以下数学级数:

\n

在此输入图像描述

\n

该代码工作正常:

\n
1 + 1 + 1.5 + 1 + 0.416667 + 0.125 + 0.029167=5.070833\n
Run Code Online (Sandbox Code Playgroud)\n

现在我用$主题变量替换了匿名状态变量$_,看看它是否工作相同。它没有:

\n
1 + 0.5 + 0.5 + 0.5 + 0.5 + 0.5 + 0.5=4\n
Run Code Online (Sandbox Code Playgroud)\n

我希望它能$_像匿名状态变量一样增加自身$,但事实并非如此。

\n

有人可以解释为什么$在这个特定的代码中可以工作但$_不能吗?

\n

rai*_*iph 7

TL;DR代码按预期工作。我将在下面解释这是怎么回事。尝试使用$_状态变量来代替是行不通的。

\n
\n

看起来$_甚至不像匿名状态变量那样自行增加$

\n
\n

它不会增加到相同的值,但它会按应有的方式增加。

\n

序列开始:

\n
1, { ([+] 1 .. ++$ ) / [\xc3\x97] 1 .. ++$ }\n
Run Code Online (Sandbox Code Playgroud)\n

序列中的第一个值是1。然后执行该块以获取序列的其余值,并将其$_设置为先前的值。(我知道你知道这一点,但我会在这个答案中非常明确和详细,这样你就很容易发现你的错误,并且对于其他可能根本不了解 Raku 的读者来说也更容易尝试遵循。)

\n

值生成器块的第一次执行将生成序列中的第二个值。$_被赋值1,并且块执行,将两个++$_s 替换为它们评估的值,变为:

\n
([+] 1 .. 2 ) / [\xc3\x97] 1 .. 3\n
Run Code Online (Sandbox Code Playgroud)\n

归约[+]将其 RHS 强制到一个列表,然后将该列表中的所有数字相加。1 .. 2产生列表(1,2),其所有数字的总和当然是3

\n

归约[\xc3\x97]将其 RHS 强制为一个列表,然后将该列表中的所有数字相乘。1 .. 3产生列表(1,2,3),其所有数字的乘积当然是6.

\n

因此整体表达式的计算结果为:

\n
3 / 6 # which is 0.5\n
Run Code Online (Sandbox Code Playgroud)\n

为了获取序列的下一个$_(第三个)值,该块将再次执行,这次使用分配0.5

\n

以下是所有步骤,分为不同的部分:

\n
$_ = 0.5;\nsay ++$_;          # 1.5\nsay ++$_;          # 2.5\nsay list 1 .. 1.5; # (1)\nsay list 1 .. 2.5; # (1 2)\nsay [+] 1;         # 1\nsay [\xc3\x97] 1, 2;      # 2\nsay 1/2;           # 0.5\n
Run Code Online (Sandbox Code Playgroud)\n

所以序列中的第三个值也是 0.5

\n

该块的第三次执行,为了获取序列中的第四个值,与前一个相同(因为$_再次设置为0.5),因此结果再次为0.5。依此类推,无穷无尽。

\n
\n
\n

我在互联网上搜索了一些,包括官方 Raku 文档,以了解$和之间的细微差别$_,但我无法理解它。有人可以解释一下吗?

\n
\n

现在,我将暂时假设您知道这些差异 - 状态变量在其封闭闭包的执行生命周期内维护其状态,但它$_只是一个词法变量,与使用 声明的变量相同my,因此每次都会重置封闭的闭包在其生命周期内重新输入 - 但只是感到困惑,因为您认为$_没有递增(或者可能是其他细节,例如list 1 .. 2.5Yieling (1,2))。如果这个假设不正确 - 如果您希望有人进一步详细说明您不确定状态变量和“普通”(非状态维护)词汇变量之间或之间的某些差异$_和其他变量之间的某些差异,请发表评论。谢谢。

\n
\n

您生成的序列是基于已知 N 来计算第 N 项的。递增状态变量正是正确的工具。相反,在我看来,了解前一项的价值根本没有帮助,这反过来又建议使用$_也没有帮助(除非您为其分配状态变量的值,但为什么呢?)。

\n