2012-05-18 1 views
3

Я хочу узнать, как изменить значение переменной, объявленной в связывании связывания функции Clojure. Ниже приведен код, который я использую. Я хочу, чтобы функция возвращала объект 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)))))) 

Примечание: Функция "открытого файла читателя ниже:

(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 вы можете вернуть full-text, когда line is null, и recur если нет.


Хотя, я предлагаю вам проверить функцию 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), когда вы в конечном итоге вернете его. Однако Морис Ривз предлагает более идиоматическое решение Clojure в his answer.

4

let bindings, как и аргументы функции, неизменяемы, поэтому вы не можете изменить их значение.

3

Вы не можете мутировать привязки из let. Просто невозможно. То, что вы пытаетесь выполнить, может быть выполнено с помощью slurp, как упомянуто другими, но если вы хотите идти по маршруту, который вы собираетесь, можно вернуть содержимое буферизованного считывания, используя комбинацию строк-seq и применяются, как показано ниже:

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

вы можете прочитать больше о линии-сл здесь: http://clojuredocs.org/clojure_core/clojure.core/line-seq

И еще о применить здесь: http://clojuredocs.org/clojure_core/clojure.core/apply

 Смежные вопросы

  • Нет связанных вопросов^_^