为什么使用花括号初始化一些哈希值,有些带圆括号?

Ada*_*m S 17 perl hash

我正在查看以下代码演示嵌套哈希:

my %HoH = (
    flintstones => {
        husband   => "fred",
        pal       => "barney",
    },
    jetsons => {
        husband   => "george",
        wife      => "jane",
        "his boy" => "elroy",  # Key quotes needed.
    },
    simpsons => {
        husband   => "homer",
        wife      => "marge",
        kid       => "bart",
    },
);
Run Code Online (Sandbox Code Playgroud)

为什么使用括号初始化最上面的哈希(起始行1),而使用花括号初始化子哈希?

来自python背景我必须说Perl很奇怪:).

mob*_*mob 29

来自Perl背景我发现Perl也很奇怪.

使用括号初始化哈希(或数组).哈希是一组字符串和一组标量值之间的映射.

%foo = ( "key1", "value1",  "key2", "value2", ... );   #  % means hash
%foo = ( key1 => "value1",  key2 => "value2", ... );   # same thing
Run Code Online (Sandbox Code Playgroud)

大括号用于定义哈希引用.所有引用都是标量值.

$foo = { key1 => "value1", key2 => "value2", ... };    #  $ means scalar
Run Code Online (Sandbox Code Playgroud)

哈希值不是标量值.由于散列中的值必须是标量,因此不可能将散列用作另一个散列的值.

%bar = ( key3 => %foo );     # doesn't mean what you think it means
Run Code Online (Sandbox Code Playgroud)

但是我们可以使用散列引用作为另一个散列的值,因为散列引用是标量.

$foo = { key1 => "value1", key2 => "value2" };
%bar = ( key3 => $foo );
%baz = ( key4 => { key5 => "value5", key6 => "value6" } );
Run Code Online (Sandbox Code Playgroud)

这就是为什么你看到围绕带括号的列表列表的括号.

  • 只是为了完整性...虽然'key3 =>%foo`确实不能做到这一点,`key3 => \%foo`添加了一个引用,这是一个非常简单的方法,可以让它做到你想做的事情在那种情况下. (5认同)

jus*_*ime 7

本质区别(....)用于创建哈希.{....}用于创建哈希引用

my %hash  = ( a => 1 , b => 2 ) ;
my $hash_ref  = { a => 1 , b => 2 } ;
Run Code Online (Sandbox Code Playgroud)

更详细一点 - {....}创建一个匿名哈希并返回对它的引用,它与标量一致$hash_ref

编辑,以提供更多细节


ike*_*ami 6

首先,parens什么都不做,只改变优先权.它们从不与列表创建,哈希创建或哈希初始化无关.

例如,以下两行是100%等效的:

{   a => 1, b => 2   }
{ ( a => 1, b => 2 ) }
Run Code Online (Sandbox Code Playgroud)

例如,以下两行是100%等效的:

sub f { return ( a => 1, b => 2 ) }    my %hash = f(); 
sub f { return   a => 1, b => 2   }    my %hash = f(); 
Run Code Online (Sandbox Code Playgroud)

其次,一个不使用初始化哈希{ }; 一个人使用它创建一个哈希.{ }相当于my %hash;,除了散列是匿名的.换一种说法,

{ LIST }
Run Code Online (Sandbox Code Playgroud)

基本上是一样的

do { my %anon = LIST; \%anon }
Run Code Online (Sandbox Code Playgroud)

(但不创建词法范围).

匿名哈希允许一个人写

my %HoH = (
    flintstones => {
        husband   => "fred",
        pal       => "barney",
    },
    jetsons => {
        husband   => "george",
        wife      => "jane",
        "his boy" => "elroy",
    },
    simpsons => {
        husband   => "homer",
        wife      => "marge",
        kid       => "bart",
    },
);
Run Code Online (Sandbox Code Playgroud)

代替

my %flintstones = (
    husband   => "fred",
    pal       => "barney",
);
my %jetsons = (
    husband   => "george",
    wife      => "jane",
    "his boy" => "elroy", 
);
my %simpsons = (
    husband   => "homer",
    wife      => "marge",
    kid       => "bart",
);
my %HoH = (
    flintstones => \%flinstones,
    jetsons     => \%jetsons,
    simpsons    => \%simpsons,
);
Run Code Online (Sandbox Code Playgroud)