不是所有的引用都被取消引用了吗?
Are all references not dereferenced the same?
我正在构建一个程序,其中包含多个我希望能够反复使用的例程。哦,我也是 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";
并且我将每个数组的每个单元格的值打印在一行上,每行之间有一个 space。伟大的!实际上,我将其作为一个单独的程序工作,根据随机值在母版中出现的顺序对来自母版的随机生成文件进行排序。现在,我正在尝试使其他子例程通用并可通过引用重用,但我在取消引用它们时运气不佳。例如:
@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 求助!
您可能将此数组引用存储在某个数组中。这意味着您现在拥有一个包含一个元素的数组:数组引用。 (引用是您如何在 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
returns 一个引用,它是一个标量值,然后可以用作任何其他标量,但必须取消引用以生成数组内容。
Data::Dumper 是一个很好的核心工具,用于在调试时确定变量中的确切内容。
use Data::Dumper;
print Dumper \@array;
这取决于您如何处理订阅中的这些引用。这里有一些注意事项
如果您传递引用并使用该引用
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
(当然除非它与 return 相关——被它覆盖,或者 return 被 push
编辑到上面)。
另一点:传递给数组的参数在 @_
中使用别名,因此如果在子程序中使用 $_[0]
(等),那么您将直接更改调用者中的数据。
从显示的内容可以清楚地看出 @lines_r
有一个元素,它本身是一个数组引用。如果没有看到代码,很难说它是如何到达那里的。一种可能是您从某个函数 return 编辑了一个 arrayref,return \@local_ary
,您没有在调用者中取消引用,而只是将它添加到 @this
或 @that
(引用通过 $list_r
).
题中代码的几点评论
sub 前面的 &
具有微妙的效果,您几乎肯定不需要。很久很久以前它曾经被需要,但现在不需要也不应该用于 "normal" 通话。
数组通过引用传递给子程序,这很好,因为它避免了可能的大量数据复制。但是,你清楚return一个列表,因为它是直接赋值给数组的。如果那些数组可能有很多数据更好 return 引用,并在调用者中取消引用它
my $ra = func(...); # func() returns an array reference
my @ary = @$ra;
或
my @ary = @{ func(...) };
我会考虑 总是 return 对包含数据的数组进行引用(而不是 return 中的一小部分标量变量集合一个列表,其中的选择仅取决于呼叫者的偏好)。
但最重要的是,还要考虑通常没有理由取消引用 returned arrayref 以创建另一个数组;它还有更多的数据副本,这很昂贵,但无论如何您都可以使用数组引用执行您需要的任何操作(例如,请参见 this post 的末尾)。
最后,如果您通过引用传递数组并将 return 分配给同一数组,请务必非常小心。
我正在构建一个程序,其中包含多个我希望能够反复使用的例程。哦,我也是 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";
并且我将每个数组的每个单元格的值打印在一行上,每行之间有一个 space。伟大的!实际上,我将其作为一个单独的程序工作,根据随机值在母版中出现的顺序对来自母版的随机生成文件进行排序。现在,我正在尝试使其他子例程通用并可通过引用重用,但我在取消引用它们时运气不佳。例如:
@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 求助!
您可能将此数组引用存储在某个数组中。这意味着您现在拥有一个包含一个元素的数组:数组引用。 (引用是您如何在 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
returns 一个引用,它是一个标量值,然后可以用作任何其他标量,但必须取消引用以生成数组内容。
Data::Dumper 是一个很好的核心工具,用于在调试时确定变量中的确切内容。
use Data::Dumper;
print Dumper \@array;
这取决于您如何处理订阅中的这些引用。这里有一些注意事项
如果您传递引用并使用该引用
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
(当然除非它与 return 相关——被它覆盖,或者 return 被 push
编辑到上面)。
另一点:传递给数组的参数在 @_
中使用别名,因此如果在子程序中使用 $_[0]
(等),那么您将直接更改调用者中的数据。
从显示的内容可以清楚地看出 @lines_r
有一个元素,它本身是一个数组引用。如果没有看到代码,很难说它是如何到达那里的。一种可能是您从某个函数 return 编辑了一个 arrayref,return \@local_ary
,您没有在调用者中取消引用,而只是将它添加到 @this
或 @that
(引用通过 $list_r
).
题中代码的几点评论
sub 前面的 &
具有微妙的效果,您几乎肯定不需要。很久很久以前它曾经被需要,但现在不需要也不应该用于 "normal" 通话。
数组通过引用传递给子程序,这很好,因为它避免了可能的大量数据复制。但是,你清楚return一个列表,因为它是直接赋值给数组的。如果那些数组可能有很多数据更好 return 引用,并在调用者中取消引用它
my $ra = func(...); # func() returns an array reference
my @ary = @$ra;
或
my @ary = @{ func(...) };
我会考虑 总是 return 对包含数据的数组进行引用(而不是 return 中的一小部分标量变量集合一个列表,其中的选择仅取决于呼叫者的偏好)。
但最重要的是,还要考虑通常没有理由取消引用 returned arrayref 以创建另一个数组;它还有更多的数据副本,这很昂贵,但无论如何您都可以使用数组引用执行您需要的任何操作(例如,请参见 this post 的末尾)。
最后,如果您通过引用传递数组并将 return 分配给同一数组,请务必非常小心。