在 Perl 中,当您 return 来自子的散列时,什么是 "quick way" 来访问特定值?

In Perl when you return a hash from a sub what is the "quick way" to acess a specific value?

在 Perl 中,它接缝,没有“简单”的方法来直接处理从子返回的散列,或者我是否遗漏了什么?

我想要这样的东西。

print ( (hash()){One} ); # Not a thing!

您可以使用数组来执行此操作,因为返回的值构成一个列表。

print ( (arr())[0] );

但对于一个不切它的散列。我想出了一些方法来让它发挥作用。

print ( ${{hash()}}{One} );
print ( 0+{hash()}->{One} );

但他们似乎有点蹩脚。我的意思是,对于这么简单的事情,这很难阅读和引用恶作剧接缝。

这里是上下文的更多代码。

use strict;
use warnings;

### ARRAY
sub arr {
    my @arr = (
        1,
        2,
        3,  
    );
    return @arr;
}

print ( (arr())[0] ); #Output is 1; 

### HASH
sub hash {
    my %hash = (
        One   => 1,
        Two   => 2,
        Three => 3,
    ); 
    return %hash;
}

my %hash = hash();


#print ( (hash()){One} );       # Does not work
print ( $hash{One}  );          # Output is 1
print ( (hash())[0] );          # Output will be One, Two or Three
print ( (hash())[1] );          # Output will be 1, 2, 3
print ( ${{hash()}}{One} );     # Output is 1
print ( 0+{hash()}->{One} );    # Output is 1;
# 0+ because Perl gives syntax error otherwise. Not sure why (Scalar context?) but one mystery at a time. 

子例程不return散列,而是值列表。此列表可以转换为散列。

给定一个 return 为偶数大小列表的子项,我将使用以下表达式来访问哈希条目:

+{hash()}->{One}

前导 + 有时需要从语句级块 {...}1 中消除散列引用文字 {...} 的歧义。一元加号是空操作,只强制表达式上下文,而 0+ 会将值转换为数字。

1.虽然在这个特定的例子中,歧义是由于 print(FILEHANDLE LIST) syntax,其中文件句柄可以用大括号括起来。

如果您可以控制尝试 return 散列的函数,则可能值得考虑改为 return 散列引用。您的示例将如下所示:

sub hashref {
    # alternatively: "return { One => 1, ... };"
    my %hash = (
        One   => 1,
        Two   => 2,
        Three => 3,
    ); 
    return \%hash;
    #      ^-- create a reference to the hash
}

my %hash = hashref()->%*;  # or "%{hashref()}". Note that this makes a copy

print( hashref()->{One} );  # can directly access keys

以下代码片段演示了数组引用和散列引用的用法。

当您必须操作大数组或散列时,这种方法的优势会得到跟踪——无需为副本分配内存,节省 CPU 个周期。

在某些情况下,算法可能需要创建副本,这可以通过取消引用数据结构轻松实现(参见示例)。

use strict;
use warnings;
use feature 'say';

### ARRAY
sub arr {
    my $ref_arr = [
        1,
        2,
        3,  
    ];
    return $ref_arr;
}

my $aref = arr();

say "
Array content:
    $aref->[0] $aref->[0]
    $aref->[1] $aref->[1]
    $aref->[2] $aref->[2]
";

my @array_copy = @$aref;

say "
Array copy content:
    $array_copy[0] $array_copy[0]
    $array_copy[1] $array_copy[1]
    $array_copy[2] $array_copy[2]
";

### HASH
sub hash {
    my $ref_hash = {
        One   => 1,
        Two   => 2,
        Three => 3,
    }; 
    return $ref_hash;
}

my $href = hash();

say "
Hash content:
    $href->{Three}: $href->{Three}
    $href->{Two}:   $href->{Two}
    $href->{One}:   $href->{One}
";

my %hash_copy = %$href;

say "
Hash copy content:
    $hash_copy{One}:   $hash_copy{One}
    $hash_copy{Two}:   $hash_copy{Two}
    $hash_copy{Three}: $hash_copy{Three}
";

输出

Array content:
        $aref->[0] 1
        $aref->[1] 2
        $aref->[2] 3


Array copy content:
        $array_copy[0] 1
        $array_copy[1] 2
        $array_copy[2] 3


Hash content:
        $href->{Three}: 3
        $href->{Two}:   2
        $href->{One}:   1


Hash copy content:
        $hash_copy{One}:   1
        $hash_copy{Two}:   2
        $hash_copy{Three}: 3