Clojure中接收双参数的匿名函数在reduce里如何工作?
关于Clojure reduce中二元函数的执行逻辑
你的疑问核心是对Clojure reduce的工作机制不熟悉——这个匿名函数不是只传了一个参数,而是reduce会自动帮你传入两个参数,具体逻辑如下:
1. reduce的参数结构回顾
Clojure的reduce函数接收三个参数:
- 第一个参数:二元函数(必须接受两个参数:累加器、当前遍历元素)
- 第二个参数:累加器的初始值
- 第三个参数:要遍历处理的序列
在你的代码里:
- 二元函数就是那个匿名函数
(fn [final-body-parts part] ...),其中final-body-parts是累加器,part是当前正在处理的身体部位 - 累加器初始值是
[](空向量) - 要遍历的序列是输入的
asym-body-parts(非对称身体部位列表)
2. 具体执行流程
reduce会自动遍历asym-body-parts序列,每次迭代都做这些事:
- 把当前累加器的值传给匿名函数的第一个参数
final-body-parts - 把序列里的当前元素传给匿名函数的第二个参数
part - 执行匿名函数,将返回值作为下一次迭代的累加器
- 遍历完所有元素后,返回最终的累加器值
举个具体例子,假设输入的asym-body-parts是:
[{:name "left-eye" :size 2} {:name "left-hand" :size 10}]
执行过程:
- 第一次迭代:
- 累加器初始值:
[] - 当前元素:
{:name "left-eye" :size 2} - 匿名函数执行:
(into [] (set [part (matching-part part)]))→ 得到[{:name "left-eye" :size 2}, {:name "right-eye" :size 2}] - 这个结果成为下一次的累加器
- 累加器初始值:
- 第二次迭代:
- 累加器当前值:
[{:name "left-eye" :size 2}, {:name "right-eye" :size 2}] - 当前元素:
{:name "left-hand" :size 10} - 匿名函数执行:
(into 累加器 (set [part (matching-part part)]))→ 得到包含左右眼、左右手的向量
- 累加器当前值:
- 遍历结束,返回最终的完整对称身体部位列表
3. 为什么你会觉得只传了一个参数?
因为匿名函数的参数是定义在reduce的第一个参数里的,并没有在调用时手动写参数传递——这是reduce的特性:它会自动负责把累加器和当前元素注入到二元函数中,不需要你手动传参。
内容的提问来源于stack exchange,提问作者Kevin Kraft
相关产品推荐
相关产品推荐

