是否可以修改let绑定?

时间:2012-05-18 17:57:21

标签: variables clojure let

我想了解如何更改在Clojure函数的let绑定中声明的变量的值。下面是我正在使用的代码。我希望函数返回java.lang.String对象,该对象包含String中包含的文本。

(defn read-text-from-file
  {:doc "fn read-text-from-file is used to output in \"string\"
format the text in a file."}
  [#^String file-name]
  (let [buff-reader (open-file-reader file-name)]
  (loop [full-text "" line (.readLine buff-reader)]
    (when line
      (-> full-text (.concat line))
;      (println full-text)
      (recur (-> file-name (.concat line)) (.readLine buff-reader))))))

注意:“open-file-reader”功能如下:

(defn open-file-reader
  {:doc "This is used to open a file, ready for reading"}
  [file-name]
  (let [file-object (java.io.File. file-name)
        buff-reader (-> file-object (java.io.FileReader.)
                        (java.io.BufferedReader.))]
    buff-reader))

3 个答案:

答案 0 :(得分:8)

let中的绑定是不可变的,不能反弹。即使您可以重新绑定它们,您的问题仍然存在于代码中的其他位置。您需要做的是使用if特殊表单而不是when宏。使用if,您可以在line is null时返回full-text,而在slurp时返回recur


虽然,我建议您查看his answer功能,它可以为您完成所有这些。

user=> (doc slurp)
-------------------------
clojure.core/slurp
([f & opts])
  Opens a reader on f and reads all its contents, returning a string.
  See clojure.java.io/reader for a complete list of supported arguments.
nil

如果您仍希望自己实现此功能,我建议您至少使full-text成为StringBuilder。然后,当您最终返回时,可以通过说(str full-text)将其转换为String。但是,Maurice Reeves在{{3}}中提供了更为惯用的Clojure解决方案。

答案 1 :(得分:4)

让绑定(如函数参数)是不可变的,因此您无法更改它们的值。

答案 2 :(得分:3)

你不能改变let的绑定。只是不可能。您正在尝试完成的事情可以通过其他人提到的slurp来完成,但是如果您想要走的路线,可以使用line-seq的组合返回缓冲读取的内容。申请如下:

(defn fetch-file-text [file-name]
     (with-open [rdr (clojure.java.io/reader file-name)]
          (apply str (line-seq rdr)))) 

您可以在此处详细了解line-seq:http://clojuredocs.org/clojure_core/clojure.core/line-seq

更多关于在这里申请: http://clojuredocs.org/clojure_core/clojure.core/apply