【问题标题】:Why does this map statement in Perl not compile?为什么 Perl 中的这个 map 语句不能编译?
【发布时间】:2010-09-21 05:12:52
【问题描述】:

这失败了:

my @a = ("a", "b", "c", "d", "e");
my %h = map { "prefix-$_" => 1 } @a;

出现此错误:

Not enough arguments for map at foo.pl line 4, near "} @a"

但这有效:

my @a = ("a", "b", "c", "d", "e");
my %h = map { "prefix-" . $_ => 1 } @a;

为什么?

【问题讨论】:

    标签: perl hash map


    【解决方案1】:

    因为 Perl 猜测的是 EXPR(例如哈希引用)而不是 BLOCK。这应该有效(注意“+”符号):

    my @a = ("a", "b", "c", "d", "e");
    my %h = map { +"prefix-$_" => 1 } @a;
    

    http://perldoc.perl.org/functions/map.html

    【讨论】:

      【解决方案2】:

      我更喜欢这样写

      my %h = map { ("prefix-$_" => 1) } @a;
      

      为了显示意图,我返回一个 2 元素列表。

      【讨论】:

        【解决方案3】:

        来自perldoc -f map

                   "{" starts both hash references and blocks, so "map { ..."
                   could be either the start of map BLOCK LIST or map EXPR, LIST.
                   Because perl doesn’t look ahead for the closing "}" it has to
                   take a guess at which its dealing with based what it finds just
                   after the "{". Usually it gets it right, but if it doesn’t it
                   won’t realize something is wrong until it gets to the "}" and
                   encounters the missing (or unexpected) comma. The syntax error
                   will be reported close to the "}" but you’ll need to change
                   something near the "{" such as using a unary "+" to give perl
                   some help:
        
                     %hash = map {  "\L$_", 1  } @array  # perl guesses EXPR.  wrong
                     %hash = map { +"\L$_", 1  } @array  # perl guesses BLOCK. right
                     %hash = map { ("\L$_", 1) } @array  # this also works
                     %hash = map {  lc($_), 1  } @array  # as does this.
                     %hash = map +( lc($_), 1 ), @array  # this is EXPR and works!
                     %hash = map  ( lc($_), 1 ), @array  # evaluates to (1, @array)
        
                   or to force an anon hash constructor use "+{"
        
                     @hashes = map +{ lc($_), 1 }, @array # EXPR, so needs , at end
        
                   and you get list of anonymous hashes each with only 1 entry.
        

        【讨论】:

          【解决方案4】:

          另外,做你正在做的事情的另一种方法,初始化哈希,你可以这样做:

          my @a = qw( a b c d e );
          my %h;
          @h{@a} = ();
          

          这将为五个键中的每一个创建 undef 条目。如果你想给他们所有真实的价值,那就这样做吧。

          @h{@a} = (1) x @a;
          

          您也可以使用循环显式执行此操作;

          @h{$_} = 1 for @a;
          

          【讨论】:

            【解决方案5】:

            我认为

            map { ; "prefix-$_" => 1 } @a;
            

            更惯用,因为它指定它是一个语句块而不是哈希引用。你只是用一个空语句开始它。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-04-17
              • 1970-01-01
              • 2011-02-03
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-12-02
              • 1970-01-01
              相关资源
              最近更新 更多