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

Raku中duckmap方法的实际作用是什么?为何与deepmap表现差异大?

理解Perl 6中duckmap的行为逻辑

哈哈,这个问题确实容易搞混,我刚接触duckmap的时候也懵过!咱们一步一步拆解为什么会得到[9,9]这个结果。

核心区别:duckmap vs deepmap

首先得明确这两个方法的核心逻辑差异:

  • deepmap:是「强制递归遍历」——不管当前元素是什么,只要它是可迭代(Iterable)的,就直接深入内部,直到遇到非可迭代元素,再应用你的块。这也是为什么你的测试中它的表现完全符合预期,把每个数字都平方了。
  • duckmap:是「鸭子类型驱动的遍历」——它的优先级是先尝试用你的块处理当前元素:
    1. 如果块对当前元素执行后返回非Nil的值,就直接把这个值加入结果列表,不会再深入元素内部;
    2. 只有当块执行后返回Nil(也就是块“处理不了”这个元素),且元素是可迭代的,它才会递归深入元素内部继续处理。

为什么你的测试会返回[9,9]?

你的块是*²,也就是{ $_ ** 2 }的简写。当这个块作用到顶层的两个数组元素时:

  1. 对于[1,2,3]:Perl 6会尝试把数组转换成数值类型来执行平方运算。在Perl 6中,数组的Numeric转换默认返回数组的元素个数(即elems方法的结果)。[1,2,3]有3个元素,所以3²=9,块成功返回9;
  2. 对于[[4,5],6,7]:同样,这个数组的元素个数也是3,平方后得到9,块也成功返回9。

因为块对两个顶层元素都返回了非Nil的值(9),所以duckmap直接把这两个9放进结果,完全不会去深入数组内部遍历里面的数字!

如何让duckmap像deepmap一样工作?

如果你想让duckmap递归处理所有内部数字,需要让块在遇到可迭代元素时返回Nil,触发它的深入逻辑。比如:

my $list = [[1,2,3],[[4,5],6,7]];
say $list.duckmap( -> $elem {
    $elem ~~ Numeric ?? $elem² !! Nil
});
# 输出:[[1 4 9] [[16 25] 36 49]]

这里的逻辑很简单:如果元素是数值类型,就返回它的平方;否则返回Nil,duckmap就会自动深入这个可迭代元素内部,继续处理里面的元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:42:27