为什么`$ v =()= split`返回1?

时间:2012-08-28 09:14:20

标签: perl

perldoc说“标量上下文中的列表赋值返回列表赋值右侧的元素数”但是当我尝试这段代码时:

perl -e '$_="aaaaa";print $v=(()=split //)'

输出为1让我感到困惑。 (我期望的答案是5。)

有人可以解释一下吗?

4 个答案:

答案 0 :(得分:15)

根据split文件:

  

当分配给列表时,如果省略LIMIT,或者为零,则Perl提供   限制一个大于列表中的变量数< ...>

由于您指定了空列表,split只返回1个结果,这个结果数正好在您的变量中结束。

答案 1 :(得分:8)

split有一些疯狂的超魔法,它可以让它知道它在左侧有一个列表的作业的右侧,并根据它调整其行为该列表中的项目数。

这在perlfunc中描述为“避免不必要的工作”,但您发现由该优化引起的行为存在可观察到的差异。

要查看发生了什么的证据,请通过Deparse运行脚本,如下所示:

perl -MO=Deparse -e '$_="aaaaa";print $v=(()=split //)'

更新:我一直在寻找实现此功能的代码,而这并不是我预期的结果。实际上,优化由赋值运算符(op.c:Perl_newASSIGNOP)执行。分裂对其背景知之甚少。

答案 2 :(得分:-1)

为什么要分配一个空数组? ()=(split //)位。那将会结束 - 嗯,好吧,一团糟。或者,就你的情况而言,一个大小为1的数组并不多。

另外,这太过模糊了。 perl因为只写而声名狼借,所有修改$ _并使用它并没有帮助其他人 - 或者你 - 了解正在发生的事情。

尝试类似

的内容
perl -e '$v = (split //, "aaaaa"); print "$v\n"'

或者,如果您希望复制测试的行为:

perl -e '$v = () = (split //, "aaaaa"); print "$v\n"'

答案 3 :(得分:-2)

是的,但是:

perl -e '$_="aaaaa";print $v=(split //)'

给出了5,以及

perl -e '$_="aaaaa";print $v=(@x=split //)'

也许你的left-value()正在丢弃额外的数组元素?

编辑:顺便说一下:

perl -e '$_="aaaaa";print $v=(($x,$y)=split //)'

返回3,因为$ v = ...命令的右视图给出:

($ x,$ y,(a,a,a))

所以在原始情况下,()=split //会返回((a,a,a,a,a))(只有一个元素)

编辑:错误的数组表示法,结果错误,因为我的测试用例的最后一分钟已更改