作为没有临时变量的键值对的子例程参数

Subroutine arguments as key-value pairs without a temp variable

在 Perl 中,我一直喜欢参数传递的键值对样式,

fruit( apples => red );

我经常这样做:

sub fruit {
    my %args = @_;
    $args{apples}
}

纯粹是为了紧凑并且有不止一种方法来做到这一点,有没有办法:

没有:


已尝试

没有哈希就无法执行哈希查找 (${...}{...})。但是你可以创建一个匿名散列。

my $apples  = ${ { @_ } }{apples};
my $oranges = ${ { @_ } }{oranges};

您也可以使用更简单的 post-dereference 语法

my $apples  = { @_ }->{apples};
my $oranges = { @_ }->{oranges};

虽然那样效率很低。您将为每个参数创建一个新的散列。这就是通常使用命名哈希的原因。

my %args = @_;
my $apples  = $args{apples};
my $oranges = $args{oranges};

但是,另一种方法是使用哈希切片。

my ($apples, $oranges) = @{ { @_ } }{qw( apples oranges )};

以下是post-derefence版本,但只有5.24+[1]:

my ($apples, $oranges) = { @_ }->@{qw( apples oranges )};

  1. 如果您使用以下内容,它在 5.20+ 中可用:

    use feature qw( postderef );
    no warnings qw( experimental::postderef );
    

如果你更关心紧凑性而不是效率,你可以这样做:

sub fruit {
    print( +{@_}->{apples}, "\n" );

    my $y = {@_}->{pears};

    print("$y\n");
}

fruit(apples => 'red', pears => 'green');

使用 +{@_}->{apples} 而不是 {@_}->{apples} 的原因是它与没有 printprint BLOCK LIST 语法冲突(或其他一些消除歧义的方法)。