10

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

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

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

有人可以解释一下吗?

4

4 回答 4

15

根据split文档:

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

由于您指定了空列表,split因此只返回 1 个结果,而这个结果数正是您的变量中的结尾。

于 2012-08-28T09:52:42.027 回答
8

split它有某种疯狂的超魔力,可以让它知道它何时位于左侧有列表的作业的右侧,并根据该列表中的项目数调整其行为。

这被描述perlfunc为“为了避免不必要的工作”,但您发现该优化导致的行为存在明显差异。

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

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

更新:我去寻找实现这个的代码,它不是我期望的。实际上优化是由赋值运算符 ( op.c:Perl_newASSIGNOP) 执行的。split 对其上下文知之甚少。

于 2012-08-28T09:45:54.317 回答
-1

为什么要分配给一个空数组?位()=(split //)。这最终会导致 - 嗯,一团糟。或者,在您的情况下,一个大小为 1 的数组中没有太多内容。

而且,这太晦涩难懂了。perl 以只写而闻名,所有修改 $_ 和使用它并不能帮助其他人 - 或者你 - 了解正在发生的事情。

尝试类似的东西

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

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

perl -e '$v = () = (split //, "aaaaa"); print "$v\n"'
于 2012-08-28T09:22:29.237 回答
-2

对,但是 :

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

给出 5,以及

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

也许你的左值()正在删除额外的数组元素?

编辑:顺便说一句:

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

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

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

所以在你原来的情况下,()=split //返回 ( ( a , a , a , a , a ) ) (它只有一个元素)

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

于 2012-08-28T09:21:36.373 回答