You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl 6中`* > 20 && * %% 5`用于grep为何结果异常?

Perl 6中WhateverCode与逻辑运算符结合的陷阱解析

这是个非常典型的Perl 6 WhateverCode与逻辑运算符搭配时的坑,我来给你拆解清楚背后的逻辑:

为什么你的两种写法会得到异常结果?

当你写 * > 20 && * %% 5 时,Perl 6会把它解析成 (* > 20) && (* %% 5)——也就是两个独立的单参数WhateverCode用逻辑与连接。但这里有个关键的Perl 6规则:任何非空的Callable(包括WhateverCode)在布尔上下文中都会被判定为True。

所以:

  • (* > 20) 作为一个合法的Callable,本身就是True,因此整个&&表达式会直接返回第二个WhateverCode * %% 5。这就导致你的grep实际上只筛选了能被5整除的元素,完全忽略了“大于20”的条件,和你看到的(15 20 25 30 35)结果完全吻合。
  • 同理,* %% 5 && * > 20 会因为第一个Callable * %%5 是True,直接返回* >20,所以grep只筛选大于20的元素,这也解释了为什么37会被选中(它大于20,但不能被5整除)。

正确的写法有哪些?

你测试里的几种正确写法都踩中了要点:确保两个条件都作用于同一个元素:

  • 显式代码块:{ $_ > 20 && $_ %% 5 }
    这里$_明确绑定到grep传递的每个元素,两个条件都针对同一个值判断,逻辑清晰且结果正确。
  • 使用Junction函数all():all(* > 20, * %% 5)
    all()是Perl 6里组合“与”条件的惯用方式,它会把多个WhateverCode打包成一个整体,要求每个元素同时满足所有条件。
  • 显式Lambda:-> $a { $a > 20 && $a %% 5 } 或 -> $a { all($a > 20, $a %% 5) }
    显式声明参数$a,强制两个条件都作用于同一个参数,从根源上避免了WhateverCode的绑定歧义。

总结

记住这个规则:不要直接用逻辑运算符(&&/||)连接多个WhateverCode,它们不会组合成针对同一参数的条件,反而会因为Callable的布尔特性短路,只返回其中一个条件。如果要组合多条件,优先用all()/any()这类Junction函数,或者显式的代码块、Lambda。

内容的提问来源于stack exchange,提问作者chenyf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:01:57