我正在使用此函数写入Clojure中的文件。
(defn writelines [file-path lines]
(with-open [wtr (clojure.java.io/writer file-path)]
(doseq [line lines] (.write wtr line))))
但是这总是会产生这个错误:
IllegalArgumentException No matching method found: write for
class java.io.BufferedWriter in
clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:79)
我在这里做错了什么?
答案 0 :(得分:17)
首先,您的功能适用于许多输入:
Clojure 1.3.0
user=> (defn writelines [file-path lines]
(with-open [wtr (clojure.java.io/writer file-path)]
(doseq [line lines] (.write wtr line))))
#'user/writelines
user=> (writelines "foobar" ["a" "b"])
nil
user=> (writelines "quux" [1 2])
nil
然而,当你试图传递奇怪的东西时,我们会得到你描述的错误:
user=> (writelines "quux" [#{1}])
IllegalArgumentException No matching method found: write for class java.io.BufferedWriter clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:79)
此错误是因为BufferedWriter
有write
的多个重载版本,而且clojure不知道要调用哪个版本。在这种情况下,冲突的是write(char[])
和write(String)
。使用字符串("a"
)和整数(1
等输入)时,clojure知道调用方法的String
版本,但使用其他内容(例如,clojure集,#{1}
)clojure无法决定。
如何确保writelines
的输入确实String
或使用str
函数对其进行字符串化呢?
另外,请查看spit
function。
答案 1 :(得分:1)
试试这个:
(defn writelines [file-path lines]
(with-open [wtr (clojure.java.io/writer file-path)]
(binding [*out* wtr]
(doseq [line lines] (print wtr line)))))
如果您查看BufferedWriter的文档,您将看不到与调用write
的方式相对应的方法(哎呀,我错过了继承的方法,傻傻的我!)。我认为绑定到*out*
更容易(除非你也想输出调试信息,在这种情况下它可能有点棘手)。
答案 2 :(得分:0)
通过异常消息,行不是字符串,整数(字符串)或int数组的序列。