从返回值引用参数

时间:2012-01-05 11:16:38

标签: perl

假设我们有一个子程序返回一个引用

sub aspirin {
    my @items = qw(some items in here);
    return \@items;
}

另一个采用数组引用的子程序

sub beetroot (\@) {
    my $lst = shift;
    print "$_\n" for @$lst;
}

我希望从aspirin获取数组并使用它beetroot。我想做一些事情(接近 A

my $L = aspirin;
beetroot $L;

但是翻译抱怨,我需要做以下事情(接近 B ):

my $L = aspirin;
beetroot @$L;

所以我的问题是:

  • 为什么 A 的方法不起作用?该参数实际上是一个数组引用,这就是我们想要的;
  • 是否需要整个列表内容的副本而没有分配的解除引用(如方法 B 中的那个)? (我猜不是,因为没有明确的副本)。

感谢您的回答

2 个答案:

答案 0 :(得分:6)

原型\@并不意味着数组引用。这意味着给我一个数组,但我会将它作为参数引用(参见perldoc perlsub

引用:

  

任何反斜杠原型字符都代表了一个实际的论点   绝对必须从那个角色开始。作为部分传递的值   @_的{​​{1}}将参考实际论证   子程序调用,通过将"\"应用于该参数获得。

或者,换句话说,不要使用原型,除非你真的知道他们做了什么。

答案 1 :(得分:1)

存在Perl原型来修改解析器的行为,这很少需要。这也不例外。

如果“beetroot”没有任何其他参数,那么您应该使用@_而不是数组引用。

sub aspirin {
    my @items = qw'some items in here';
    return @items if wantarray; # return a list in list context
    return \@items;
}

sub beetroot {
    print "$_\n" for @_;
}

my $L = aspirin;
beetroot @$L;

# the follow examples require the version of aspirin from this answer

my @L = aspirin;
beetroot @L;

beetroot aspirin; # aspirin called in list context

如果您只想输入元素列表,这将带来额外的好处,即您不必解决解析器。

这适用于新版本,但不适用于问题中的版本。

beetroot qw'some items in here';
beetroot aspirin; # aspirin called in list context

要使其与问题中的那个一起使用,您必须创建一个匿名数组。有趣的是,这也适用于这个答案中的版本。

beetroot @{ [qw'some items in here'] };
# the follow examples use the version of aspirin from this answer
beetroot @{ [aspirin] };
beetroot @{ scalar aspirin };
beetroot @{ aspirin };

如果您真的希望“beetroot”使用数组引用。 我会这样写。

sub beetroot{
  my($lst) = @_; # similar to my $lst = shift
  print "$_\n" for @$lst;
}

my $L = aspirin;
beetroot $L;

my @L = aspirin; # using the aspirin from this answer
beetroot \@L;

beetroot [qw'some items in here'];
# the follow examples use the version of aspirin from this answer
beetroot scalar aspirin; # force aspirin to return an array reference
beetroot [ aspirin ]; # copy the array

如果你想使用引用来减少Perl的内存占用,或者你有其他输入“beetroot”,我只会这样写。

相关问题