代码之家  ›  专栏  ›  技术社区  ›  Mark McDonald

为什么Perl在声明时将哈希元素视为列表上下文?

  •  3
  • Mark McDonald  · 技术社区  · 15 年前

    #!/usr/bin/perl -w
    
    use strict;
    use warnings;
    
    sub foo {
        return wantarray ? () : "value1";
    }
    
    my $hash = {
        key1 => foo(),
        key2 => 'value2'
    };
    
    use Data::Dumper;
    print Dumper($hash);
    

    我得到以下输出:

    $VAR1 = {
      'key1' => 'key2',
      'value2' => undef
    };
    

    当我期望:

    $VAR1 = {
      'key1' => 'value1',
      'key2' => 'value2'
    };
    

    我知道散列是一种偶数大小的数组(正如我得到的“散列赋值中的元素奇数”警告所证明的),但散列元素只能是标量, 为什么编译器会给它数组上下文?

    2 回复  |  直到 9 年前
        1
  •  7
  •   Quentin    15 年前

    因此:

    my $hash = {
        key1 => foo(),
        key2 => 'value2'
    };
    

    指:

    my $hash = {
        'key1', foo(), 'key2', 'value2'
    };
    

    列表中的每个表达式都在列表上下文中求值。你可以打电话来解决这个问题 scalar foo()

        2
  •  3
  •   brian d foy    15 年前

    匿名哈希构造函数为其中的内容提供列表上下文,因为它需要一个键和值列表。就是这样,因为就是这样。我们没有在代码中表示Perl哈希的方法,因此您必须使用一个列表来替换键和值。这个 => 表示法可以帮助我们直观地理解,但并没有发挥帮助Perl理解散列类型的神奇作用。

    当前上下文传播到子例程调用等,就像在任何其他情况下一样。

    这允许您使用列表操作构建哈希:

     my $hash = { 
          a => 'A',  
          map( uc, 'd' .. 'f' ),
          return_list( @args ), 
          z => 'Z' 
          };
    

    如果您需要在标量上下文中使用某些内容,只需使用 scalar :

     my $hash = { 
          a => 'A',  
          map( uc, 'd' .. 'f' ),
          'g' => scalar return_item( @args ), 
          z => 'Z' 
          };