在 Perl 中,当您从子返回哈希时,访问特定值的“快速方法”是什么?

Dom*_*nic 1 perl hash

在 Perl 中,它似乎没有“简单”的方法来直接处理从子程序返回的哈希值,还是我遗漏了一些东西?

我想要这样的东西。

print ( (hash()){One} ); # Not a thing!
Run Code Online (Sandbox Code Playgroud)

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

print ( (arr())[0] );
Run Code Online (Sandbox Code Playgroud)

但对于一个不能削减它的哈希值。我想出了一些方法来让它发挥作用。

print ( ${{hash()}}{One} );
print ( 0+{hash()}->{One} );
Run Code Online (Sandbox Code Playgroud)

但他们看起来有点蹩脚。我的意思是,这很难阅读,而且对于这样一个简单的事情来说,引用恶作剧是不合适的。

这是更多上下文代码。

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. 
Run Code Online (Sandbox Code Playgroud)

amo*_*mon 6

子例程不返回哈希值,而是返回值列表。该列表可以转换为散列。

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

+{hash()}->{One}
Run Code Online (Sandbox Code Playgroud)

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

1. 尽管在这个特定实例中,歧义是由于print(FILEHANDLE LIST)语法造成的,其中文件句柄可以用花括号括起来。

如果您可以控制尝试返回哈希的函数,则可能值得考虑返回哈希引用。您的示例将如下所示:

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
Run Code Online (Sandbox Code Playgroud)

  • 后一种方法的优点是,它避免了必须“展平”子程序中的哈希并在调用方中构建新的哈希。 (2认同)