perl将引用分配给子例程

perl将引用分配给子例程,perl,reference,subroutine,Perl,Reference,Subroutine,我在一个子例程中使用@来获取一个参数,该参数被指定为数组的引用,但结果不会显示为数组引用 我的代码在下面 my @aar = (9,8,7,6,5); my $ref = \@aar; AAR($ref); sub AAR { my $ref = @_; print "ref = $ref"; } 这将打印1,而不是数组引用,但如果我用shift替换@u,打印结果将是引用 有人能解释一下为什么我不能用@uu-to-me获得引用吗?这是关于Perl的。这是语言的一个重要方面 表

我在一个子例程中使用@来获取一个参数,该参数被指定为数组的引用,但结果不会显示为数组引用

我的代码在下面

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

my $ref = \@aar;

AAR($ref);

sub AAR {
   my $ref = @_;
   print "ref = $ref";
}
这将打印1,而不是数组引用,但如果我用shift替换@u,打印结果将是引用

有人能解释一下为什么我不能用@uu-to-me获得引用吗?

这是关于Perl的。这是语言的一个重要方面

表情像

my $var = @ary;
您正在尝试将数组分配给标量

从目前的情况看,这是没有意义的,所发生的事情是,右侧被计算为数组的元素数,并被分配给
$var

为了更改该行为,您需要向赋值运算符提供“列表上下文”。†在本例中,您可以这样做

my ($var) = @ary;
现在我们将一个列表(数组元素)分配给一个列表(变量列表,这里只有
$var
),在这里它们被一对一地分配。因此这里
@ary
的第一个元素被分配给
$var
。请注意,这句话对“列表”这一难以捉摸的概念进行了歪曲

所以在你的情况下,你想要

my ($ref) = @_;
根据需要,将
@
中的第一个元素分配给
$ref

或者,您可以使用删除并返回
@
的第一个元素,在这种情况下,标量上下文赋值就可以了

my $ref = shift @_;
在这种情况下,您也可以这样做

my $ref = shift;
由于默认情况下,
shift
@
上工作

当您要在分配输入时删除输入的第一个元素,以便剩余的
@
非常适合进一步处理时,此选项非常合适。这在面向对象代码中最常用


值得一提的是,Perl中的许多操作符和内置工具根据它们在什么上下文中被调用而不同

对于某些细节,一个现成的示例是regex match操作符,它在标量上下文中返回true/false(1/空字符串),但在列表上下文中返回实际匹配,而有关更明显的区别,请参见,例如。Perl的每个角落都有上下文敏感的行为

用户级子例程可以通过使其以这种方式运行


† 看见 进行详细讨论

"
查看它,例如

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

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

sub AAR {
   my ($ref) = @_;
   print "ref = $ref\n";
}
这将打印类似于
ref=ARRAY(0x5566c89a4710)
的内容

然后可以使用引用访问数组元素,如下所示:

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

谢谢你的解释。你的回答让我更了解perl语法。@HenryLu不客气。我建议您通读
perldata
(第一个链接),然后四处寻找其他资源。另请参阅一个从长远来看可能有助于了解的附录:不是()创建列表,因为
1,2,3
1..5
@foo
都是列表,只要它们在列表上下文中(例如,子例程的参数或foreach迭代的列表)。这只是一种特殊情况:赋值左侧的括号将其转换为列表赋值。在赋值右边的列表周围通常需要括号,这只是为了优先。更多:@Grinnz这应该对OP有帮助,然后我要补充一点,“列表”是一个难以捉摸的概念(但我不是为了这个而去那里)。此外,由于LHS
()
将列表上下文施加在
=
op上,RHS列表被复制到LHS列表中(嗯,“列表”中的变量)。因此,我们确实通过
()
“获取一个列表”——非常松散(也不精确)地说。同样,不能通过语法创建“列表”是正确的(它在堆栈上,该术语与运算符在给定上下文中的工作方式有关),但这会导致语义混乱:)@Grinnz Edited,试图软化术语“列表”的松散用法。(一旦用它松散地解释事情,就会出现问题。)