3

我想了解如何更改在 Clojure 函数的 let 绑定中声明的变量的值。下面是我正在使用的代码。我希望该函数返回 java.lang.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))
4

3 回答 3

8

中的绑定let是不可变的,不能被反弹。即使您可以重新绑定它们,您的问题也存在于代码的其他地方。您需要做的是使用if特殊形式而不是when宏。使用 anif你可以返回full-text什么时候line是 nullrecur什么时候不是。


不过,我建议您查看该slurp功能,它可以为您完成所有这些工作。

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)然后,当您最终返回它时,您可以通过说 , 将其转换为字符串。但是,Maurice Reeves 在他的回答中提供了一个更惯用的 Clojure 解决方案。

于 2012-05-18T18:06:20.087 回答
4

let 绑定,就像函数参数一样,是不可变的,所以你不能改变它们的值。

于 2012-05-18T18:07:41.620 回答
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

于 2012-05-18T19:28:27.690 回答