Clojure中向函数传递Map参数异常:v2键未传入问题排查
问题描述
我定义了如下函数:
(defn add-column-2 [catalog columns] (println "Add-column-2") (update-in catalog ["streams" (column->tap-stream-id (:v1 columns))] add-column-to-stream (:v1 columns) (:v2 columns)))
我期望columns参数为包含:v1、:v2键的Map,以便在函数内使用这两个参数。我通过以下方式调用该函数:
(reduce add-column-2 empty-catalog all-columns)
其中all-columns是包含:v1、:v2键的Map,empty-catalog定义为:
(def empty-catalog {"streams" {}})
但调试时发现:
catalog参数符合预期;columns参数仅传入了含:v1键的Map条目,:v2键未传入。
请问为何:v2键未传递到add-column-2函数?如何传递完整的Map作为参数?
注:我曾参考过Stack Overflow相关问题,但尝试后仍无法获取:v2键(返回nil)。
问题分析与解决
原因
Clojure中reduce遍历Map时,默认会逐个迭代Map的键值对条目,每个条目是形如[key value]的向量,而非整个Map。当你的all-columns是{:v1 x :v2 y}这样的单个Map时,reduce会分两次调用add-column-2:
- 第一次调用:
catalog为empty-catalog,columns为[:v1 x] - 第二次调用:
catalog为第一次执行后的结果,columns为[:v2 y]
这就导致函数中(:v2 columns)在第一次调用时返回nil,(:v1 columns)在第二次调用时返回nil,看起来像是:v2没被传递。
解决方法
场景1:all-columns是单个包含:v1/:v2的Map
不需要用reduce,直接调用函数即可:
(add-column-2 empty-catalog all-columns)
场景2:all-columns是多个包含:v1/:v2的Map的集合
如果你的实际需求是遍历一组这样的Map(比如[{:v1 a :v2 b} {:v1 c :v2 d}]),需要确保reduce遍历的是集合中的每个完整Map。如果之前误把单个Map当作集合传入,要将其包装为集合(比如向量):
; 假设all-columns是单个Map,包装成向量后传入reduce (reduce add-column-2 empty-catalog [all-columns])
调试验证
可以在函数中添加打印语句,直观查看每次传入的columns结构:
(defn add-column-2 [catalog columns] (println "Add-column-2, columns content:" columns) (update-in catalog ["streams" (column->tap-stream-id (:v1 columns))] add-column-to-stream (:v1 columns) (:v2 columns)))
内容的提问来源于stack exchange,提问作者stuck
相关产品推荐
相关产品推荐

