【问题标题】:Printing an array within double quotes在双引号内打印数组
【发布时间】:2011-07-05 17:20:37
【问题描述】:
my @a = (1,2,3,4,5);

print @a;      #output: 12345

print "\n";

print "@a";    #output: 1 2 3 4 5

通过将数组的名称放在双引号中来打印数组,会在输出的每个索引值之间放置一个空格。它是如何做到的?为什么print @a; 打印不一样?这两种类型的需求是什么?我的意思是你什么时候会使用print @a; 而不是print "@a";,反之亦然。

【问题讨论】:

    标签: perl syntax


    【解决方案1】:

    更好的问题:为什么它不打印像 array{0x1232ef} 这样的东西。 Print 假设打印字符串输出,@a 不是标量。

    哎呀,更好:这是一个标量上下文,所以为什么不打印5,它是数组中元素的数量。方法如下:

    print scalar @a;
    

    会打印。

    相反,print 命令正在尝试做一些你想要做的事情,而不是你说你想要做的事情。

    我们来看看这个小程序:

    @a = qw(a b c d e);
    
    print "@a";         #prints "a b c d e"
    print "\n";
    
    print @a;           #prints "abcde"
    print "\n";
    
    print @a . "\n";    #prints "5"
    
    print scalar @a;    #prints "5"
    

    注意print @a 打印abcde,但如果我在末尾添加\n,它会在标量上下文中打印@a

    查看Perldoc on print(尝试命令perldoc -f print。在大多数系统上,整个Perl 文档都可以通过perldoc 获得)

    * print LIST
    * print
    
    Prints a string or a list of strings. Returns true if successful[...]
    

    啊!如果给定一个列表,它将打印一个字符串列表。

    $, 的当前值(如果有)打印在每个 LIST 项目之间。 $\ 的当前值(如果有)在打印整个 LIST 之后打印。因为 print 需要一个 LIST,所以 LIST 中的任何内容都在列表上下文中进行评估,包括您传递给 print 的返回列表的任何子例程。

    让我们尝试一个新程序:

    @a = qw(a b c d e);
    
    $, = "--";
    print "@a";         #prints "a b c d e"
    print "\n";
    
    print @a;           #prints "a--b--c--d--e"
    print "\n";
    
    print @a . "\n";    #prints "5"
    
    print scalar @a;    #prints "5"
    

    嗯...$, 在列表元素之间添加了双破折号,但它不影响引号中的@a。而且,如果perldoc中提到了$,,为什么大家都在喋喋不休地谈论$"

    我们来看看perldoc perlvar

    * $LIST_SEPARATOR
    * $"
    
    When an array or an array slice is interpolated into a double-quoted string or a
    similar context such as /.../ , its elements are separated by this value. Default
    is a space. For example, this:
    
    print "The array is: @array\n";
    
    is equivalent to this:
    
    print "The array is: " . join($", @array) . "\n";
    
    Mnemonic: works in double-quoted context.
    

    所以,这就解释了一切!

    $" 默认为单个空格,$, 默认为空。这就是为什么我们得到了我们得到的!

    还有一个程序...

    @a = qw(a b c d e);
    
    $, = "--";
    $" = "++";
    print "@a";         #prints "a++b++c++d++e"
    print "\n";
    
    print @a;           #prints "a--b--c--d--e"
    print "\n";
    
    print @a . "\n";    #prints "5"
    print scalar @a;    #prints "5"
    

    【讨论】:

      【解决方案2】:

      当在字符串中插入数组时,假设您可能希望能够在视觉上区分元素;当您打印一个列表时,假设您只希望该数据连续输出。两者都是可配置的; $,(默认为'')被插入到正在打印的列表的元素之间,而$"(默认为'')被插入到插入到字符串中的数组元素之间。

      【讨论】:

        【解决方案3】:

        首先,您将参数列表传递给print,然后依次打印每个参数。

        在第二个中,您将一个数组插入到一个字符串中,然后打印结果。 当一个数组在一个字符串中插值时,值由$"分隔,默认为

        【讨论】:

          【解决方案4】:

          当 Perl 在一个插值字符串中看到一个数组时,它会使用 join 重写它:

          print "@array";
          

          变成

          print join($" => @array);
          

          默认情况下,$" 的值等于一个空格。

          您可以通过将更改本地化为 $" 来配置此行为

          print "@array";     # '1 2 3 4 5'
          {
              local $" = '';  # "
              print "@array"; # '12345'
          }
          print "@array";     # '1 2 3 4 5' 
          

          您可以看到 Perl 如何使用核心 B::Deparse 模块的 -q 选项重写您的插值字符串:

          $ perl -MO=Deparse,-q -e 'print "@array"'
          print join($", @array);
          -e syntax OK
          

          【讨论】:

            【解决方案5】:

            双引号中的数组

            “Array Interpolation” section of the perldata documentation 解释了"@a" 值中的插入空间如何到达那里:

            数组和切片通过将元素与$" 变量中指定的分隔符($LIST_SEPARATOR,如果指定了use English;)连接起来,被插入双引号字符串,默认情况下是空格。以下是等价的:

            $temp = join($", @ARGV);  # " for benefit of StackOverflow hiliter
            system "echo $temp";
            system "echo @ARGV";
            

            这意味着print "@a"单个 标量参数传递给print。相比之下,您的示例中的print @a 通过了五次。

            打印多个值

            perlfunc documentation on print 用参数列表解释了 print 的含义。

            print LIST

            $, 的当前值(如果有)打印在每个 LIST 项目之间。

            perlvar documentation on $,

            Handle->output_field_separator( EXPR )
            $OUTPUT_FIELD_SEPARATOR
            $OFS
            $,强>

            打印操作符的输出字段分隔符。如果已定义,则在每个 print 的参数之间打印此值。默认为undef

            助记符:当您的print 语句中有, 时打印的内容。

            因为$, 默认为未定义值,所以您会看到print 输出其参数而没有分隔符。明确地说,您问题中的代码相当于

            print join("", @a);
            

            为什么?

            print 的行为差异并不是特例。数组插入到所有双引号字符串as described above。对Google code-search hits for print "@... 的快速调查似乎表明print "@foo" 的频繁使用是调试输出,如

            sub foo {
              print "args = @_\n" if $debug;
              ...;
            }
            

            Mark Dominus 用来为值可能包含空格的列表提供可见分隔符的一个方便技巧是

            sub foo {
              if ($debug) {
                local $" = "][";
                print "args = [@_];  # e.g., [foo][1][3.14159]
              }
              ...;
            }
            

            @a 包含输出行,例如

            @a = map "  - $_\n", @error_messages;
            print @a;
            

            在值之间插入隐式空格会影响我精心构建的格式:

             - 鬼鬼祟祟的,先生
               - 那只脚的丑陋将永远困扰我的梦想
                - 你为什么要那样做?!

            Perl 努力做到我们的意思,即使我们提出的要求不一致。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2022-01-13
              • 1970-01-01
              • 2015-11-17
              • 2021-12-11
              • 1970-01-01
              • 1970-01-01
              • 2022-10-15
              相关资源
              最近更新 更多