perl 分配对子例程的引用

perl assign reference to subroutine

我在子例程中使用@_ 来获取指定为数组引用的参数,但结果未显示为数组引用。

我的代码在下面。

my @aar = (9,8,7,6,5);

my $ref = \@aar;

AAR($ref);

sub AAR {
   my $ref = @_;
   print "ref = $ref";
}

这将打印 1 ,而不是数组引用,但如果我用 shift 替换 @_ ,打印结果将是一个引用。

任何人都可以解释为什么我无法使用 @_ 获得参考吗?

这与 Perl 中的 context 有关。这是语言的一个重要方面。

这样的表达
my $var = @ary;

尝试将数组分配给标量。

这没有意义,实际情况是右侧被计算为数组元素的数量, 被分配给 $var.

为了更改该行为,您需要向赋值运算符提供“列表上下文”。 在这种情况下,您需要

my ($var) = @ary;

现在我们将一个列表(数组元素)分配给一个列表(变量,这里只有 $var),它们是一对一分配的。所以这里@ary的第一个元素赋值给了$var。请注意,此声明与难以捉摸的“列表”概念无关。

所以在你的情况下你想要

my ($ref) = @_;

并且 @_ 中的第一个元素根据需要分配给 $ref

或者,您可以使用 shift 删除 return @_ 的第一个元素,在这种情况下,标量上下文分配很好

my $ref = shift @_;

在这种情况下你也可以这样做

my $ref = shift;

因为 shift 默认适用于 @_

当您想要删除输入的第一个元素时,这很有用,因为它正在分配,以便剩余的 @_ 非常适合进一步处理。它通常在面向对象的代码中完成。


非常值得指出的是,Perl 中的许多运算符和内置工具会根据调用它们的上下文而有所不同。

对于某些细节,仅举几个例子:标量上下文中的正则表达式匹配运算符 returns true/false(1/空字符串),但列表上下文中的实际匹配, readdir returns a single entry in scalar context but all of them in list context, while localtime 显示出更明显的差异。这种上下文相关的行为存在于 Perl 的每个角落。

可以通过 wantarray.

使用户级子程序以这种方式运行

参见 详细讨论

例如看in perlretut and in perlop

当您将数组分配给标量时,您得到的是数组的大小。您将一个参数(对数组的引用)传递给 AAR,这就是您得到 1.

的原因

要获取实际参数,请将局部变量放在大括号中:

sub AAR {
   my ($ref) = @_;
   print "ref = $ref\n";
}

这会打印类似 ref = ARRAY(0x5566c89a4710) 的内容。

然后您可以像这样使用引用来访问数组元素:

print join(", ", @{$ref});