Perl的带字符串参数的foreach

时间:2019-02-04 06:00:30

标签: perl

Perldocs仅表示foreach循环“迭代普通列表值” https://perldoc.perl.org/perlsyn.html#Foreach-Loops,但有时我会看到它们带有字符串参数,例如以下示例:

foreach (`curl example.com 2>/dev/null`) {
    # iterates 50 times
}

foreach ("foo\nbar\nbaz") {
    # iterates just 1 time. Why?
}

传递这样定义的字符串的行为是吗?另外,为什么像示例中那样,通过传递反引号命令返回的字符串和文字字符串来产生完全不同的结果?

4 个答案:

答案 0 :(得分:5)

在标量上下文中,反引号返回一个包含所有包含的命令输出的标量。但是foreach (...)在列表上下文中评估反引号,这会将输出分成一个列表,每个元素一行。

答案 1 :(得分:3)

问题围绕context展开,这是Perl中很多事情的关键概念。

foreach循环需要一个列表进行迭代,因此它强加了列表上下文来构建您在文档中看到的list values。该列表可以由文字qw(a b c)组成,并且可以具有一个元素;这是您的第二个示例,其中给出了一个字符串,形成了一个迭代的单元素列表。

列表也可以来自在列表上下文中求值的表达式;这是你的第一个例子。许多操作会根据上下文产生不同的收益,qx就是mob答案中解释的运算符。这是要注意和注意的地方。表达式也可以返回单个值,而不管上下文如何。那么它只是用来填充列表。

答案 2 :(得分:1)

来自perldoc -f qx

  

在列表上下文中,返回行列表(但是您已使用$ /或$ INPUT_RECORD_SEPARATOR定义了行);如果命令失败,则返回空列表。

来自perldoc perlsyn

  

复合语句

     

[...]

     

LABEL foreach VAR(列表)块

答案 3 :(得分:-2)

字符串不是列表。如果要遍历字符串中的字符,则需要

foreach my $character (split('', "foo\nbar\nbaz")) {

我认为您可能会将Perl与Python混淆:

>>> for c in "foo\nbar\nbaz":
...    print c
... 
f
o
.... remainder deleted ....
a
z
>>>

如其他答案所指出,backticks / qx{}从列表上下文中的已执行命令返回输出行列表。