习惯的方法写的Clojure代码反复从控制台读取线?(Idiomatic way to write

2019-07-30 10:49发布

最近我在写这需要一点CLI脚本来多次从控制台读取日期(日期读取计算的数量和每个时间可能会有所不同)。 样品Ruby代码给你的想法:

dates = x.times.collect { print "Enter date: "; Date.parse(gets.chomp) }

只是它的心里很不舒服,我用Clojure写的剧本,彼时使用一些比较难看的代码swap!loop...recur 。 我想知道什么最干净的方式来实现Clojure中所期望的效果会。 (Clojure中确实有dotimes ,但它不会保留评估身体......因为可能从强调纯函数式编程语言可以预期的返回值。)

Answer 1:

如果你的目标是完全相同的序列落得x用户输入的日期,然后:

(for [line (repeatedly x read-line)] (DateFormat/parse line))

或使用map

(map DateFormat/parse (repeatedly x read-line))

当心Clojure的懒惰序列:用户将被要求在需要的时候进入更多的日期。 如果你的目标是为用户在一次输入所有时间(在启动时说的),然后使用doall

(map DateFormat/parse (doall (repeatedly x read-line)))

这将同时读取所有日期,但会解析它们懒洋洋地还在,所以日期格式验证可以在你的程序要晚得多失败。 您可以移动doall一个级别解析及时,以及:

(doall (map DateFormat/parse (repeatedly x read-line)))

你也可以使用一个辅助函数提示读行:

(defn read-line-with-prompt [prompt]
  (print prompt)
  (read-line))

然后更换read-line与之一:

#(read-line-with-prompt "Enter date: ")

要么

(partial read-line-with-prompt "Enter date: ")


Answer 2:

读线到达文件结尾时返回零。 在控制台上,当你按CTRL-d(在Windows CTRL-Z)即到。

您可以使用此代码来利用这一点:

(doseq [line (repeatedly read-line) :while line]
    (do-something-with line))

如果你必须阅读线固定数量的,你可以使用:

(repeatedly n read-line)


Answer 3:

你可以这样做:

(defn read-dates [n] 
     (doall  (for [_ (range n)] (java.util.Date/parse (read-line)))))

(def my-dates (read-dates 5)) ;Read 5 dates from console


文章来源: Idiomatic way to write Clojure code for repeatedly reading lines from the console?