函数如何将其参数列表作为数组引用返回

时间:2011-01-12 09:41:52

标签: perl

我如何编写一个返回其参数作为数组引用的函数?

2 个答案:

答案 0 :(得分:12)

sub f {
   return [@_];
}

$ref = f(2, 3, 5);
print "@$ref\n";

[@foo]构造创建对新的匿名数组(@foo的副本)的引用,而\@foo构造创建对@foo数组的引用,内容可能会稍后改变。

答案 1 :(得分:2)

有几种方法可以创建一个子程序,将其参数作为数组返回:

sub array {[@_]}  # returns an array reference that is a copy of its argument

sub array_verbose {  # the same as array(), but spelled out
    my @copy = @_;
    return \@copy;
}

sub capture {\@_}  # returns a reference to the actual argument array

arraycapture之间存在一些重要差异:

my ($x, $y) = (3, 4);

my $array = array $x, $y;
my $capture = capture $x, $y;

say "@$array, @$capture";  # prints '3 4, 3 4'

$x++;

say "@$array, @$capture";  # prints '3 4, 4 4'

$$capture[1] *= 2;

say "@$array, @$capture";  # prints '3 4, 4 8'

say "$x $y";  # prints '4 8'

正如这些示例所示,array()生成的数组是按值复制的,这些值与原始参数无关。由capture()生成的数组保留其参数列表的双向别名。

另一个区别在于速度。 capture()array()快约40%,因为它不必复制数组的元素(甚至不需要查看它们)。这种速度差异当然会根据参数列表的长度而变化。

capture()甚至没有触及其元素的附加效果是,如果使用通常会分配内存的参数,则在触及参数之前不会发生该分配:

my %hash;
my $hashcap = capture $hash{a}, $hash{b}, $hash{c};

say join ', ' => keys %hash; # prints nothing

$_++ for @$hashcap;

say join ', ' => keys %hash; # prints 'c, a, b'

在我自己的代码中,我通常将capture()拼写为cap()或者只是将其写入内联:

my $y = sub{\@_}->(map $_**2, 1..10);