请看下面的代码:
$scalar = 10;
subroutine(\$scalar);
sub subroutine {
my $subroutine_scalar = ${$_[0]}; #note you need the {} brackets, or this doesn't work!
print "$subroutine_scalar\n";
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,您可以看到写下的注释"请注意您需要{}括号,否则这不起作用!" .请解释为什么我们不能使用相同的声明的原因:
my $subroutine_scalar = $$_[0];
Run Code Online (Sandbox Code Playgroud)
即不使用花括号.
很多人已经在这里给出了正确答案.我想添加一个我发现有启发性的例子.您可以阅读perldoc perlref中的文档以获取更多信息.
您的问题是模糊不清,您有两个操作$$并[0]处理相同的标识符_,结果取决于首先执行的操作.我们可以通过使用支撑花括号使其不那么模糊${ ... }.$$_[0]可能(对于人类而言)可能意味着:
${$$_}[0]- 取消引用标量$_,然后取其第一个元素.${$_[0]}- 获取0数组的元素@_并取消引用它.正如你所看到的,这两种情况涉及到完全不同的变量,@_和$_.
当然,对于Perl来说它并不含糊,我们只是得到第一个选项,因为在键查找之前执行解除引用.我们需要支持花括号来覆盖这种解除引用,这就是为什么你的例子没有支持括号就"工作"的原因.
您可能会考虑为子例程稍微混淆一些功能.您可以分两个阶段完成,而不是尝试一次做两件事(获取参数并取消引用它):
sub foo {
my $n = shift;
print $$n;
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们采取的第一个参数关@_有shift,然后取消对它的引用.干净简单.
但是,大多数情况下,您不会使用对标量变量的引用.在这些情况下,您可以使用箭头运算符->
my @array = (1,2,3);
foo(\@array);
sub foo {
my $aref = shift;
print $aref->[0];
}
Run Code Online (Sandbox Code Playgroud)
我发现使用箭头运算符比$$语法更好.