2012-05-18 115 views
3

我想了解如何更改在Clojure函數的let綁定中聲明的變量的值。以下是我正在使用的代碼。我希望函數返回java.lang.String對象,該對象包含String中包含的文本。是否可以修改let綁定?

(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)))))) 

注意:函數'開放文件讀者低於:

(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)) 
+2

哪一部分,你要完成的東西需要改變一個let綁定? –

回答

8

let的綁定是不可變的,不能反彈。即使您可以重新綁定它們,您的問題仍然存在於代碼中的其他地方。您需要做的是使用if特殊窗體而不是when宏。使用if時,如果不是line is nullrecur,則可以返回full-text


雖然,我建議你檢查一下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在his answer中提供了一個更習慣的Clojure解決方案。

4

讓綁定,如函數參數,是不可變的,所以你不能改變它們的值。

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)))) 

你可以閱讀更多關於線-seq的位置:http://clojuredocs.org/clojure_core/clojure.core/line-seq

,更多的是應用在這裏: http://clojuredocs.org/clojure_core/clojure.core/apply