“For”失败但“循环”有效

时间:2013-07-08 09:03:43

标签: clojure

我想使用SQLKorma执行一些SQL语句。起初我写了以下代码:

(let [sqls (-> (slurp "resources/database.sql")
              (str/split #";")
              butlast)]
  (for [sql sqls]
      (k/exec-raw sql)))

但由于原因不明,这不起作用。 for循环完全被跳过。然而,这有效:

(let [sqls (-> (slurp "resources/database.sql")
              (str/split #";")
              butlast)]
  (loop [sqls sqls]
    (if (not (empty? sqls))
      (do
        (k/exec-raw (first sqls))
        (recur (rest sqls))))))

为什么会这样?为什么for循环失败?

2 个答案:

答案 0 :(得分:8)

for很懒。请改用doseq

(doseq [sql sqls]
  (k/exec-raw sql))

答案 1 :(得分:4)

for创建一个懒惰的序列。只有当你以某种方式实际使用它时,Clojure才会执行延迟序列的每个元素。如果您只需要副作用,则应使用dorun强制执行延迟序列。

在您的情况下,我建议您使用map

(->> (str/split (slurp "resources/database.sql")
                #";")
     butlast
     (map k/exec-raw)
     dorun)

doseqsee mtyaka's answer)代替for循环

(doseq [sql (-> (slurp "resources/database.sql")
                (str/split #";")
                butlast)]
  (k/exec-raw sql))

我更喜欢map版本,但doseq的工作速度更快。