Clojure:用返回值强制评估代码

时间:2016-08-31 09:26:17

标签: clojure clojure-java-interop

由于函数的行为非常扭曲,我的代码出现了问题。

我使用google-api在BigQuery中传输数据。在Java中,您创建一个名为Bigquery.Tabledata.InsertAll的对象(请求),然后执行它

TableDataInsertAllResponse response = request.execute();

(来自Google的示例代码)

但正如您所看到的,执行是在返回响应时产生副作用的事情。

我用Clojure(以分块方式)再现它

(defn load-bq
  [client project-id dataset-id table-id data & {:keys [chunk-size] :or {chunk-size 500}}]
  (let [chunks (partition-all chunk-size data)
        _ (str "Now streaming data into table : [" project-id ":" dataset-id "." table-id "]")]
    (map (partial atomic-load-bq client project-id dataset-id table-id) chunks)))

如果我尝试在repl中流式传输,它可以正常工作。但令人惊讶的是,doall在代码中不起作用,如let或with do。 这里有一个函数来说明原理

(def load-this-table
  [... data]
  (let [_ (doall (load-bq ... data))]
    (load-bq ... data)
    (do (load-bq ...data))))

此处不会加载任何内容。

我找到了一个有效的技巧,虽然它有点牵强:

(def load-this-table
  [... data]
  (let [_ (println (load-bq ... data))]
    (println (load-bq ... data))))

这两行都将执行。当然我只需要一个流媒体,所以我在这里选择了一个解决方案。

如何在不使用println的情况下强制评估此代码? 我可以使用什么力评估behing println或任何更一般的核心功能。

我的印象是,差异并不是与懒惰有关,而是与Clojure和Java之间更为根本的区别有关。也许响应必须由客户“采取”。

谢谢!

0 个答案:

没有答案