假设我编写了一个函数来解析带有with-open and clojure.java.io/reader, 的txt文件中的数据,然后我写了另一个函数来多次调用reader函数来处理数据,例如
(defn grabDataFromFile [file patternString]
(let [data (atom [])]
(with-open [rdr (clojure.java.io/reader file)]
(doseq [line (line-seq rdr)]
(if (re-matches (re-pattern patternString) line) (swap! data conj line))))
@data))
(defn myCalculation [file ]
(let [data1 (grabDataFromFile file "pattern1")
data2 (grabDataFromFile file "pattern2")
data3 (grabDataFromFile file "pattern3")]
;calculations or processes of data1, data2, data3....))
我的问题是,在这个myCalculation函数中,底层代码足够智能,只需用clojure reader打开文件一次,并获得一次性所需的所有数据?或者它是否打开和关闭文件的次数与函数grabDataFromFile的调用次数一样多? (在这个例子中,3)
后续问题是,如果读者不够聪明,如果我必须故意将“解析器”代码与“处理”代码分开,我该怎么办?
答案 0 :(得分:2)
grabDataFromFile
都会打开和关闭阅读器(退出时)。底层代码不能那么聪明,以至于函数可以在没有明确提供信息的情况下检测其调用者的上下文。
让grabDataFromFile
接受另一个函数,它是你在每一行上运行的解析器逻辑(或者它可以是你想在每一行上执行的任何函数)
(defn grabDataFromFile [file patternString process-fn]
(with-open [rdr (clojure.java.io/reader file)]
(doseq [line (line-seq rdr)]
(process-fn line))))
(defn myCalculation [file]
(let [patterns [["pattern1" (atom [])]
["pattern2" (atom [])]
["pattern3" (atom [])]]
pattern-fns (map (fn [[p data]]
(fn [line]
(if (re-matches (re-pattern p) line)
(swap! data conj line)))) patterns)
pattern-fn (apply juxt pattern-fns)]
(grabDataFromFile file pattern-fn)
;perform calc on patterns atoms
))