首页 > 解决方案 > 所有引用的取消引用都相同吗?

问题描述

我正在构建一个程序,其中包含几个我希望能够一遍又一遍地使用的例程。哦,我也是 perl 的绝对初学者,所以就是这样。所以,我有数组,我用从文件中提取的文本行填充,以便我可以解析、修改、比较等,使用用户输入或从(一个)其他文件中提取的其他数据位,具体取决于在部署子程序的程序上。

所以,我有一个子程序,我将三个数组引用传递给:

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

我在传递 sub 进行完整性检查后取消引用数组,如下所示:

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)

因此,出于某种原因,我无法使用之前使用的相同方法取消对 THIS 数组的引用。是什么赋予了?TIA 的帮助!

标签: perlreferencedereference

解决方案


这取决于您如何处理您的潜艇中的这些引用。这里有一些注意事项

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

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引用,您没有在调用者中取消引用,而只是将其添加到@thisor @that(由 引用$list_r)。


对问题中的代码的一些评论

潜艇前面&有微妙的效果,你几乎肯定不需要。很久很久以前就需要它,但现在不需要也不应该将其用于“正常”呼叫。

数组通过引用传递给子,这很好,因为它避免了可能的大量数据复制。但是,您清楚地返回了一个列表,因为它直接分配给数组。如果这些数组可能有很多数据,最好返回引用,并在调用者中取消引用

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

或者

my @ary = @{ func(...) };

我会考虑始终返回包含数据的数组的引用(而不是在列表中返回的一小部分标量变量集合,其中选择仅取决于调用者的偏好)。

但最重要的是,还要考虑通常没有理由取消引用返回的 arrayref 以创建另一个数组;它是更多的数据副本,这很昂贵,而无论如何您都可以使用数组引用做任何和所有您需要的事情(例如,请参见本文结尾)。

最后,如果您通过引用传递一个数组并将返回值分配给同一个数组,请非常非常小心您正在做的事情。


推荐阅读