什么时候在 Raku 中使用无印记变量才有意义?

use*_*475 13 variables sigils raku

Raku 符号表示基础变量的性质(例如,$scalar、@positional、%associative、&code)。

可以使用反斜杠将变量声明为无印记(例如,\some-variable),然后在不使用印记的情况下引用它(即,some-variable)。

只是想知道在什么情况下首选使用无符号变量?

Jon*_*ton 11

Declarations of the form my \a = expr introduce an alias a to the expression expr without enforcing any kind of context on it, as assignment into a sigiled variable would. Thus their primary use is when you don't want to have any of the semantics associated with any sigil.

Personally, I use them most when I am building up lazy processing pipelines and want to name the parts. As a simple example:

my $fh = open 'somefile';
my \no-comments = $fh.lines.grep({ not /^\s*'#'/ });
for no-comments -> $sig-line {
    ...
}
Run Code Online (Sandbox Code Playgroud)

A grep returns a Seq that, if iterated, will perform the operation. If I were to instead use an @-sigil variable:

my $fh = open 'somefile';
my @no-comments = $fh.lines.grep({ not /^\s*'#'/ });
for @no-comments -> $sig-line {
    ...
}
Run Code Online (Sandbox Code Playgroud)

Then while the results would be the same, the memory performance would be very different: assignment is eager unless it encounters something explicitly marked lazy, and so this would store all the non-comment lines into @no-comments and then iterate over them. Thus all those lines stay around in memory, whereas in the sigilless version then processed lines - so long as they are not stored elsewhere - can be garbage collected.

我可以使用$印记,但这意味着单个项目,这意味着如果我这样做:

my $fh = open 'somefile';
my $no-comments = $fh.lines.grep({ not /^\s*'#'/ });
for $no-comments -> $sig-line {
    ...
}
Run Code Online (Sandbox Code Playgroud)

它不会工作(它会执行循环的一次迭代,将Seqinto绑定$sig-line);我必须以某种方式克服它的项目性质:

my $fh = open 'somefile';
my $no-comments = $fh.lines.grep({ not /^\s*'#'/ });
for $no-comments<> -> $sig-line {
    ...
}
Run Code Online (Sandbox Code Playgroud)

一个相关的用途是编写不想强制执行任何上下文的通用代码时:

sub log-and-call(&foo, \value) {
    note(value.raku);
    foo(value)
}
Run Code Online (Sandbox Code Playgroud)

同样,如果我们使用,$我们可以添加一个项目包装器并可能影响foo.

我见过的其他用途:

  • 由于您无法重新绑定这样的声明,因此可以使用它向读者传达不变性。也就是说,这不是深度不变性,只是该符号引用的内容的不变性。
  • 有些人真的不喜欢印记,所以用它来避免它们。当然不是最自然的 Raku 使用方式,但各有各的用途。:-)