Arrays 何时返回数组或哈希,何时仅返回引用?
我对以下内容感到困惑。Arrays 何时返回数组或哈希,何时仅返回引用?,arrays,perl,function,hash,reference,Arrays,Perl,Function,Hash,Reference,我对以下内容感到困惑。 有时我会看到这样的例子: my %hash = get_data(); sub get_data { my %data = (); # do processing return %data; } 与数组类似 my @arrays = get_data(); sub get_data { my @data = (); # do processing return @data; } 我最初认为不能仅从函数引用返回数组或哈
有时我会看到这样的例子:
my %hash = get_data();
sub get_data {
my %data = ();
# do processing
return %data;
}
与数组类似
my @arrays = get_data();
sub get_data {
my @data = ();
# do processing
return @data;
}
我最初认为不能仅从函数引用返回数组或哈希值。所以我不明白有什么区别,什么时候我们应该优先于其他人?
它是否与垃圾收集或我们选择的数据副本过多有关?您实际上正在创建一个新数组(或哈希),该数组填充的元素与子数组中生成的元素相同:
sub get_data{
# initialize an array
my @toReturn = qw/ a b c d e f g /;
# get its location in memory
my $toReturn_ref = \@toReturn;
# print its location in memory
print "toReturn: $toReturn_ref\n";
# return the **elements** in the array (not the array itself)
return @toReturn;
}
# initialize an array
my @arr = get_data();
# get its location in memory
my $arr_ref = \@arr;
# print its location in memory
print "\"Returned\": $arr_ref\n";
这将打印如下内容:
toReturn: ARRAY(0x1df85e8)
"Returned": ARRAY(0x1debc40)
它们是不同的数组,但恰好有相同的内容。严格来说,不能从Perl子例程返回数组或哈希。Perl子例程返回列表。列表类似于数组,因为它们是值序列,但不是数组。数组是变量。列表是无名的、不可变的、暂时的数据结构,用于传递和返回值、初始化数组和散列等。它是一个非常重要的数据结构 当您写入
return@data
时,您没有返回@data
数组;您将返回它包含的值的列表。类似地,return%data
返回散列中包含的键/值对的列表。这些值可用于初始化另一个数组或散列,这就是示例中发生的情况。初始化的数组/哈希包含子例程使用的数组/哈希的(浅层)副本
要“返回”数组或散列,必须返回对它的引用。e、 g.return\@数据
或return\%数据
。这样做将返回对变量本身的引用。修改它也会影响原始阵列,因为它是相同的存储
sub是否应该返回数组/哈希作为列表(副本)或引用是编程决策。对于总是返回具有位置意义的N个值的sub(例如,localtime
内置),返回列表是有意义的。对于返回任意大列表的sub,通常最好返回一个引用,因为这样效率更高
sub甚至可以使用wantarray
根据调用方式决定返回什么。这让打电话的人决定他们想要什么
sub get_data {
my @data;
...
return wantarray ? @data : \@data;
}
my $aref = get_data(); # returns a reference
my @array = get_data(); # returns a list
函数始终返回列表。如果是
return@data
则是@data
元素的列表,如果是return%data
则是键/值%data
元素的列表,如果是\%data
则是一个元素的列表(散列引用)。您可以像以前一样将这样的列表输入哈希、数组等@mpapec:那么有什么区别呢?数组只是一个列表对象,不是吗?散列也表示为一个列表。我想我遗漏了一些重要的东西。例如,代码粘贴错误吗?数组和散列是容器,而您可以将列表视为瞬态或动态结构。和@mpapec:那么OP中的代码没有任何隐藏的bug?没有。在第一种情况下,您甚至可以返回@data
,并将其输入哈希,但是您应该确保@data
的元素数为偶数。GC呢?如果我们从一个函数返回一个引用,而该函数只要有人持有正确的引用,就不会被释放(我的意思是内存)?@Jim:正确。通过返回一个引用,您将获得阵列的一个副本,只要至少有一个引用,该副本就会持续存在。返回列表会导致阵列的多个副本,但子阵列的副本可以立即进行GC。