所有引用都不会被取消引用吗?

时间:2018-10-10 21:34:18

标签: perl reference dereference

我正在构建一个程序,该程序具有我希望能够反复使用的几个例程。哦,我也是perl的初学者,所以就这么简单。因此,我有一些数组,我填充了从文件中提取的文本行,以便可以使用用户输入或从其他文件中提取的其他数据位来解析,修改,比较等。在程序中将子例程部署到其中。

因此,我有一个子例程,我将三个数组引用传递给:

@sorted = &sort_arrays(\@order, \@ktms, \@sorted);

在将子项传递给完整性检查之后,我取消了对数组的引用,如下所示:

sub sort_arrays {
my ($ref_array, $list_array, $sorted_r) = @_;
print "@{$ref_array} \n"; print "@{$list_array} \n"; print "@{$sorted_r} \n";

,我得到了打印在一行上的每个数组的每个单元格的值,每行之间有一个空格。大!我实际上是作为一个单独的程序来工作的,它根据随机值出现在母版中的顺序对母版中随机生成的文件进行排序。现在,我正在尝试使其他子例程具有通用性并且可以与引用一起重用,但是我对取消引用它们的运气却不尽相同。例如:

@that = &get_ktms_from_program(\@this, \@that);

但是,当我尝试取消引用它们时,我得到了一个坏消息!

    print "\nEntered get_lines_from_program sub\n"; 
    my ($lines_r, $parsed_r) = @_;
    print "@{$lines_r}\n";

输出:

Entered get_lines_from_program sub
ARRAY(0x81c20dc)

因此,由于某种原因,我无法使用先前使用的相同方法来取消引用此数组。是什么赋予了? TIA寻求帮助!

2 个答案:

答案 0 :(得分:2)

这取决于您对潜艇中的潜艇的处理方式。这里有一些说明可能会有所帮助

如果您通过参考并使用参考

func(\@ary);
...
sub func {
    my ($ra) = @_;
    ...
    push @$ra, @some_values;  # changes @ary in the caller
}

然后您刚刚在呼叫者中更改了@ary

但是,如果您在子目录中创建本地副本

sub func {
    my ($ra) = @_;
    my @local_ary = @$ra;
    ...
    return \@local_ary;    # return reference to brand new @local_ary
}

然后对@local_ary所做的更改不会影响调用方中的@ary(除非它与返回的过程有关-被它覆盖,或者被返回push修饰)上。)

另一点:传递给数组的参数在@_中具有别名,因此,如果在子级中使用$_[0](例如),那么您将直接在调用方中更改数据。

从显示的内容来看,很清楚@lines_r中有一个元素,该元素本身是数组引用。您如何获得它,如果不看代码很难说。一种可能是您从某个函数return \@local_ary返回了一个arrayref,您没有在调用方中对其取消引用,而只是将其添加到@this@that(由{{1}引用)中。 }。


对问题代码的一些注释

sub前面的$list_r具有微妙的效果,您几乎肯定不需要。很久很久以前就需要使用它,但现在不需要,也不应该将它用于“正常”呼叫。

通过引用将数组传递给子数组,这很好,因为它避免了可能的大量数据复制。但是,由于列表是直接分配给数组的,因此您显然会返回一个列表。如果这些数组可能有很多数据,最好返回引用,然后在调用方中取消引用

&

my $ra = func(...);   # func() returns an array reference
my @ary = @$ra;

我会考虑总是返回带有数据的数组的引用(这与少量标量变量返回列表中的列表相反,列表中的选择仅取决于调用者的偏好)。 / p>

最后,如果通过引用传递数组并将返回值分配给同一数组,请非常谨慎地进行操作。

答案 1 :(得分:1)

您可能将此数组引用存储在某个位置的数组中。这意味着您现在拥有一个带有一个元素的数组:一个数组引用。 (参考是在Perl中嵌套数据结构的方式;请参见perllol)。当您将此数组插入字符串中时,将打印一个元素(数组引用),并且数组引用的字符串化形式类似于您看到的字符串。取而代之的是,将数组引用存储在标量变量中,无论您在哪里获取它,都可以原样将其传递给其他子例程。

use strict;
use warnings;

my $aref = sub_returning_aref();
other_sub($aref);

sub sub_returning_aref {
  my @stuff;
  return \@stuff;
}

sub other_sub {
  my ($aref) = @_;
  print "@$aref\n";
}

要记住的关键是\@array返回一个标量值的引用,然后可以将其用作任何其他标量,但是必须取消引用才能产生数组内容。

Data::Dumper是一个很好的核心工具,可用于确定调试时变量中的确切位置。

use Data::Dumper;
print Dumper \@array;