为什么clojure交换!与地图无法正常工作?

Nan*_*Qin 2 clojure

(defn get-vector []
    (let [rs (atom [])]
        (map (fn [x] (swap! rs conj x)) [1 2 3 4]) 
      @rs))

(get-vector)
Run Code Online (Sandbox Code Playgroud)

我认为这个功能应该回归[1 2 3 4]; 但是,它只返回一个空向量[].

Pio*_*dyl 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]
Run Code Online (Sandbox Code Playgroud)

我不确定你要解决什么问题 - 如果这只是一个示例代码来测试swap!工作方式,那么代码看起来还不错.否则,您可能希望使用其他解决方案,reduce并避免使用可变引用.

正如@Shlomi所建议的那样,使用doseq副作用会更加惯用:

(let [rs (atom [])]
  (doseq [x [1 2 3 4]]
    (swap! rs conj x))
  @rs)
Run Code Online (Sandbox Code Playgroud)

  • 我还注意到`map`不是副作用的惯用语,因为我们有[`doseq`](https://clojuredocs.org/clojure.core/doseq) (6认同)