Raku符号表示基础变量的性质(例如,$标量、@位置、%关联、
可以使用反斜杠(例如,\可以声明一个无符号的变量),然后在没有符号的情况下引用它(即,可以使用一些变量)。
只是想知道在什么情况下更喜欢使用无符号变量?
形式为my\a=expr
的声明在表达式expr
中引入了别名a
,而不对其强制执行任何类型的上下文,就像赋值到符号变量中一样。因此,它们的主要用途是当您不想将任何语义学与任何符号相关联时。
就我个人而言,当我构建惰性加工管道并想命名零件时,我最常使用它们。举个简单的例子:
my $fh = open 'somefile';
my \no-comments = $fh.lines.grep({ not /^\s*'#'/ });
for no-comments -> $sig-line {
...
}
grep
返回一个Seq
,如果迭代,将执行该操作。如果我要改用@
-sigil变量:
my $fh = open 'somefile';
my @no-comments = $fh.lines.grep({ not /^\s*'#'/ });
for @no-comments -> $sig-line {
...
}
然后,虽然结果是相同的,但内存性能将非常不同:赋值是急切的,除非它遇到明确标记为惰性的东西,因此这将所有非注释行存储到@no-评论
中,然后遍历它们。因此,所有这些行都留在内存中,而在无符号版本中,然后处理的行——只要它们没有存储在其他地方——可以被垃圾回收。
我可以使用$
符号,但这意味着一个项目,这意味着如果我这样做:
my $fh = open 'somefile';
my $no-comments = $fh.lines.grep({ not /^\s*'#'/ });
for $no-comments -> $sig-line {
...
}
它不起作用(它会进行一次循环迭代,将Seq
绑定到$sig-line
中);我必须以某种方式克服它的项目性质:
my $fh = open 'somefile';
my $no-comments = $fh.lines.grep({ not /^\s*'#'/ });
for $no-comments<> -> $sig-line {
...
}
一个相关的用途是在编写不想强制执行任何上下文的通用代码时:
sub log-and-call(&foo, \value) {
note(value.raku);
foo(value)
}
同样,如果我们使用$
,我们可以添加一个项目包装器并可能影响foo
的行为。
我见过的其他用途:
由于它们是常量,我喜欢在从教科书中复制算法和公式时使用它们。
它使检查错误变得更加容易。