在双引号内打印数组

时间:2011-07-05 17:20:38

标签: perl syntax

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";,反之亦然。

5 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:9)

更好的问题:为什么不打印像 array {0x1232ef} 这样的东西。打印是为了打印字符串输出,而@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中的任何内容都在列表上下文中进行评估,包括您传递给打印的返回列表的任何子例程。

让我们尝试一个新程序:

@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 :(得分:6)

在第一个实例中,您将一个参数列表传递给print,并依次打印每个参数。

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

答案 3 :(得分:1)

当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如何使用核心-q模块的B::Deparse选项重写插值字符串:

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

答案 4 :(得分:1)

双引号中的数组

“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;

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

  - sneaky-sneaky, sir
   - the hideousness of that foot will haunt my dreams forever
    - why would you do that?!

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