Arrays 为什么Perl中的串联会打印数组';s计数,而不是数组本身

Arrays 为什么Perl中的串联会打印数组';s计数,而不是数组本身,arrays,perl,printing,concat,scalar,Arrays,Perl,Printing,Concat,Scalar,例如: my @array = ("a","b","c"); print @array; #prints abc print "Array is: " . @array #prints 3 my $x = @array; # sets $x to the length of @array also. 是什么使这两个print语句不同呢?串联发生在。在标量上下文中引用数组会给出其长度。例如: my @array = ("a","b","c"); print @array; #prints

例如:

my @array = ("a","b","c");

print @array; #prints abc
print "Array is: " . @array #prints 3
my $x = @array;  # sets $x to the length of @array also.
是什么使这两个print语句不同呢?

串联发生在。在标量上下文中引用数组会给出其长度。例如:

my @array = ("a","b","c");

print @array; #prints abc
print "Array is: " . @array #prints 3
my $x = @array;  # sets $x to the length of @array also.
如果要展开数组的内容,可以使用多个选项

如果只想像在第一条语句中那样打印数组,可以将连接更改为逗号。这与原始示例的行为最为相似,包括“$”,它指定了一个分隔符,该分隔符出现在列表中的每个元素之后(包括字符串“Array is:”,以及
@Array
的最后一个元素):

您可以将它放在引号中,将其作为字符串插入,用
$”
分隔元素。请注意,
$”
默认为单个空格字符。如果需要将其连接到另一个字符串,则此选项非常有用:

print "Array is: " . "@array";
如果要连接不带分隔符的数组元素,或使用除
$“
以外的显式分隔符,可以使用
连接
。同样,这在生成字符串但不一定立即打印字符串的上下文中非常有用

print "Array is: " . join( "", @array );        # gives "abc"
print "Array is: " . join( " fred ", @array );  # gives "a fred b fred c"


注意:我在上面的标量上下文下添加了一个链接,这是马克·杰森·多米努斯(Mark Jason Dominus)的精彩解释。值得您花时间阅读。它并不长。

最后一行中执行的第一个操作是连接到标量值”数组是:为此,Perl还需要将第二个操作数@array转换为标量类型。在Perl中,数组到标量转换的约定不是所有数组元素的串联,而是元素的数量,因此您还可以打印类似于5+@array的内容。因此,表达式打印“数组为:5”


第1个print语句不必执行数组到标量的转换,因此它会打印数组内容。

Joe Z正确地认为连接运算符在标量上下文中操作,尽管这在
perldoc perlop
中没有明确说明。整个故事需要一点解释

如果您不熟悉Perl中的上下文,可能会非常混乱,因为该术语已过载。在
perlop
中,您将看到对诸如“字符串上下文”或“数字上下文”之类的内容的引用,但这些标量上下文的特殊情况会在标量上下文之后应用。例如,对于
+
运算符,假定为数字上下文。对于
运算符,假定为字符串上下文。这些不同的字符串或数字上下文的特殊情况是需要的,但并不总是清楚变量应该被视为字符串还是数字,因此Perl区分了这两个运算符。否则,“foo”将在“数值”上下文中被视为
0
,而
“foo”+“bar”
是什么意思?那是
foobar
还是
0
?因此,串联使用单独的运算符来避免歧义

您将在
perldoc perlop
中看到以下内容:

Additive Operators
   Binary "+" returns the sum of two numbers.
   Binary "-" returns the difference of two numbers.
   Binary "." concatenates two strings.
而这在perldoc术语表中:

scalar context
   The situation in which an expression is expected by its
   surroundings (the code calling it) to return a single value rather
   than a list of values. See also context and list context. A scalar
   context sometimes imposes additional constraints on the return
   value. See string context and numeric context.
对于您的情况,由于点运算符使用“字符串上下文”,我们首先得到标量值的转换,三元素数组的标量值是
3
。然后在“字符串”上下文中解释该数字,导致您发现的混乱行为

不幸的是,上下文是最让新的Perl开发人员感到困惑的事情之一,但是一旦您习惯了它,它就非常自然,可以节省大量的输入(没有双关语)

作为帮助您理解的进一步示例,以下打印了
6

$ perl -E '@a = qw(a b);@b = qw(c d e f); say @a + @b'

@a
@b
分别在标量上下文中求值,分别返回
2
4
,并在数字上下文中添加。如果将
+
运算符替换为
,则会看到打印的
24

因为@array在标量上下文中

print "Array is : @array";

print”数组是:“,@Array
更类似于OP的第一个示例(它不会隐式地连接到
$”
)。在我看来,这通常不是最有用的,但值得指出。:)这将不同于
print@Array
(元素将由默认为空格的
$”
分隔)。要仅使用字符串打印它,请执行以下操作:
print“Array is:”,@Array
(这也会添加一个分隔符,但它将是
$,
,默认为无)@hobbs:好的,我不知道
$“
,因为我避免使用大多数名为magic variables的标点符号。我将更新上面的答案。@ysth:好的,我不知道
$,
,因为我避免了大多数名为magic variables的标点符号。我会更新上面的答案。