【问题标题】:perl assign reference to subroutineperl 分配对子程序的引用
【发布时间】:2019-04-06 07:31:28
【问题描述】:

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

我的代码在下面。

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

my $ref = \@aar;

AAR($ref);

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

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

谁能解释为什么我无法使用@_ 获得参考?

【问题讨论】:

标签: perl reference subroutine


【解决方案1】:

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

类似的表达式

my $var = @ary;

尝试将数组分配给标量。

就目前而言这没有意义,发生的情况是右侧被评估为数组元素的数量, 被分配给$var。 p>

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

my ($var) = @ary;

现在我们将一个列表(数组元素)分配给一个列表(变量,这里只有$var),它们被一对一地分配。所以这里@ary的第一个元素分配给$var。请注意,这句话与“列表”这个难以捉摸的概念很不协调。

所以在你的情况下你想要

my ($ref) = @_;

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

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

my $ref = shift @_;

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

my $ref = shift;

因为shift 默认情况下适用于@_

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


值得指出的是,Perl 中的许多运算符和内置工具的行为不同,具体取决于调用它们的上下文。

对于一些细节,仅举几个例子:正则表达式匹配运算符在标量上下文中返回真/假(1/空字符串),但在列表上下文中实际匹配,readdir 返回一个标量上下文中的单个条目,但所有条目都在列表上下文中,而localtime 显示出更明显的差异。这种上下文相关的行为存在于 Perl 的每个角落。

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


Scalar vs List Assignment Operator 详细讨论

in perlretutin perlop 例如

【讨论】:

  • 感谢您的解释。您的回答让我更了解 perl 语法。
  • @HenryLu 欢迎您。我建议您通读perldata(第一个链接),然后查看perldoc 以获取其他资源。另见learn.perl.org
  • 从长远来看可能有助于了解的附录:创建列表的不是 (),因为 1, 2, 31..5@foo 都是列表,只要它们' re 在列表上下文中(例如,子例程的参数,或 foreach 迭代的列表)。这只是一种特殊情况:赋值左侧的括号将其转换为列表赋值。而且您通常需要在作业右侧的列表周围加上括号,以便优先考虑。更多:altreus.blogspot.com/2011/08/…
  • @Grinnz 这应该对 OP 有帮助,然后我要补充一点,“列表”是一个难以捉摸的概念(但我并不是为了这个而去那里)。此外,由于 LHS () 将列表上下文强加到 = op 上,因此 RHS 列表被复制到 LHS list 中(嗯,“列表”中的变量)。因此,我们确实通过()“获取列表”——非常松散(且不精确)地说。同样,不能通过语法创建“列表”是正确的(它在堆栈上,并且该术语与运算符在给定上下文中的工作方式有关)但是这进入了滑溜的语义:)
【解决方案2】:

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

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-28
    • 2011-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    相关资源
    最近更新 更多