3

我想使用 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 循环会失败?

4

2 回答 2

8

for是懒惰的。改用doseq

(doseq [sql sqls]
  (k/exec-raw sql))
于 2013-07-08T09:07:51.680 回答
4

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

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

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

doseq见 mtyaka 的回答)而不是for循环

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

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

于 2013-07-08T10:37:26.057 回答