以这种方式访问​​哈希有什么问题?

时间:2013-08-30 16:03:56

标签: perl hash

我很难理解哈希的引用和解除引用如何在perl中工作。

我有3个级别的哈希定义如下:

%languages = ( 
               'en', ( 
                       'it', ( 'pattern1', '...', 'pattern2', '...' )
                       'de', ( 'pattern1', '...', 'pattern2', '...' )
                     ) 
               'it', ( 
                       'en', ( 'pattern1', '...', 'pattern2', '...' )
                       'de', ( 'pattern1', '...', 'pattern2', '...' )
                     )
               'de', ( 
                       'en', ( 'pattern1', '...', 'pattern2', '...' )
                       'it', ( 'pattern1', '...', 'pattern2', '...' )
                     )
             );

并希望迭代第一级哈希的第二级,如下所示:

my $current_language = 'de';
while ( ( my $language, my $patterns ) = each %{ $languages{ $current_language } } )
{
  print $patterns->{'pattern1'};
}

但是我收到以下错误

Can't use string ("en") as a HASH ref while "strict refs" in use

我将不胜感激。

2 个答案:

答案 0 :(得分:11)

在Perl中,parens 排序优先。以下两行是等效的:

(1, 2, 3)
(1, (2, (3)))

因此,您实际上正在分配

( 
  en       => 'it',
  pattern1 => '...',
  pattern2 => '...' ,
  de       => 'pattern1'
  '...'    => 'pattern2'
  '...'    =>'it',
  en       => 'pattern1',
  ... # I think you got it …
);

您实际上不能嵌套哈希,而是引用嵌套哈希。您可以将{ foo => 2}用于 hashref文字,将[1, 2, 3]用于 arrayref文字

%languages = ( 
           en => { 
                   it => ['pattern1', 'pattern2'],
                   de => ['pattern1', 'pattern2'],
                 },
           ...,
         );

while (my($lang, $patterns) = each $languages{de}) {
  print "$lang has [@$patterns]\n";
}

注意:=>(又名“fat comma”运算符)与逗号的运算符相同,但可用于强调键值关系(并且可以方便地自动添加引号到未加引号左侧的字符串(裸字) - 即散列键。)

答案 1 :(得分:5)

Perl中的哈希值必须是标量,看起来您正在尝试将列表(或表示哈希的列表)分配为哈希值。幸运的是,hash references 是标量。我想你的意思是:

%languages = ( 

           'en', {
                   'it', { 'pattern1', '...', 'pattern2', '...' },
                   'de', { 'pattern1', '...', 'pattern2', '...' }
                 }, 
           'it', { 
                   'en', { 'pattern1', '...', 'pattern2', '...' },
                   'de', { 'pattern1', '...', 'pattern2', '...' }
                 },
           'de', { 
                   'en', { 'pattern1', '...', 'pattern2', '...' },
                   'it', { 'pattern1', '...', 'pattern2', '...' }
                 }
         );