Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 何时返回数组或哈希,何时仅返回引用?_Arrays_Perl_Function_Hash_Reference - Fatal编程技术网

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。