2011-01-12 92 views

回答

12
sub f { 
    return [@_]; 
} 

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

[@foo]结构创建一个新的,匿名数组(的@foo副本)的引用,而\@foo结构造成对@foo阵列,其内容可能会在以后发生变化的参考。

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);