Clojure lazy seq从一个函数体中的不同位置消耗

Clojure初学者在这里,不确定问题中的术语是否正确.

我正在使用clj-webdriver taxi api构建一个web scraper.有几个站点需要从中获取数据.以下实际上不是项目的代码,但我已经测试过并验证它说明了我的问题:

(def gh-un "my-username")
(def gh-pw "my-password")

;; print the first five "starred" alerts from my github feed
(defn get-info [url]
  (to url)
  (click "a[href='/login']")
  (input-text "input#login_field" gh-un)
  (input-text "input#password" gh-pw)
  (click "input.btn")
  (pprint (map text (take 5 (find-elements {:css "div.alert.watch_started"}))))
  (click "img.avatar")
  (click "button.dropdown-signout"))

(defn github-wrapper []
  (map get-info (repeat 3 "http://www.github.com"))
  (quit))

如果我按原样调用(github-wrapper),由于(退出)调用,浏览器窗口几乎会立即关闭.用doall包装地图调用,即(doall(map get-info(重复3“http://www.github.com”))),解决了这个问题,这表明问题是地图产生了一个懒惰的序列没有消耗,因此我没有看到调用get-info的副作用.

但是,如果我在get-info结束时删除(退出)调用,github-wrapper会按照我想要的方式执行.

我的问题是,为什么延迟序列在后一种情况下被消耗,而在前者中却没有?

最佳答案 这是因为你可能在调用github-wrapper时打印返回的地图.打印延迟序列是消费它的一种方式(与doall一起).当您在github-wrapper的末尾放置quit时,这就是返回的内容,而map只假设没有任何需要它的值.

如果希望立即实现地图,也可以使用mapv而不是map.

点赞