是否可以修改 let 绑定?
Posted
技术标签:
【中文标题】是否可以修改 let 绑定?【英文标题】:Is it possible to modify let bindings? 【发布时间】:2012-05-26 07:35:45 【问题描述】:我想了解如何更改在 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))
【问题讨论】:
您要完成的事情的哪一部分需要更改 let 绑定? 【参考方案1】:let
中的绑定是不可变的,不能被反弹。即使您可以重新绑定它们,您的问题也存在于代码的其他地方。您需要做的是使用if
特殊形式而不是when
宏。使用if
,您可以在line
is null 时返回full-text
,在没有时返回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)
将其转换为字符串。不过,Maurice Reeves 在his answer 中提供了更惯用的 Clojure 解决方案。
【讨论】:
【参考方案2】:let 绑定,就像函数参数一样,是不可变的,所以你不能改变它们的值。
【讨论】:
【参考方案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
【讨论】:
以上是关于是否可以修改 let 绑定?的主要内容,如果未能解决你的问题,请参考以下文章