(defn get-vector []
(let [rs (atom [])]
(map (fn [x] (swap! rs conj x)) [1 2 3 4])
@rs))
(get-vector)
我认为这个函数应该返回[1 2 3 4]
;
但是,它只返回一个空向量[]
。
答案 0 :(得分:10)
Clojure map
是懒惰的,因为你没有要求它的结果,它不会评估它的内容,也不会用swap!
执行你的功能。
要使其正常运行,您应该使用dorun
强制它实现其内容:
(defn get-vector []
(let [rs (atom [])]
(dorun (map (fn [x] (swap! rs conj x)) [1 2 3 4]))
@rs))
(get-vector)
;; => [1 2 3 4]
我不确定您要解决的问题是什么 - 如果这只是一个示例代码来测试swap!
的工作方式,那么该代码看起来还不错。否则,您可能希望使用其他解决方案,例如reduce
,并避免使用可变引用。
根据@Shlomi的建议,使用doseq
副作用更为惯用:
(let [rs (atom [])]
(doseq [x [1 2 3 4]]
(swap! rs conj x))
@rs)
答案 1 :(得分:1)
doseq
更惯用,但我更喜欢map
的语法,所以另一种选择是创建一个强制序列实现的maprun
:
(def maprun (comp dorun map))
(defn get-vector []
(let [rs (atom [])]
(maprun (fn [x] (swap! rs conj x)) [1 2 3 4])
@rs))
(get-vector)
这在技术上与Piotrek相同,因为maprun
仅仅是语法糖。