【问题标题】:Writing to a file in Clojure在 Clojure 中写入文件
【发布时间】:2012-01-23 09:47:34
【问题描述】:

我正在使用这个函数在 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)

我在这里做错了什么?

【问题讨论】:

  • 为了更清楚起见,您能否在您的问题中添加一个示例函数调用?很可能证实了 opqdonut 的回答。
  • 不是您问题的答案,但在这种情况下可能会很有趣:stackoverflow.com/questions/7756909/…

标签: java clojure


【解决方案1】:

首先,您的函数适用于许多输入:

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 的输入确实是Strings 或使用str 函数对其进行字符串化?

另外,看看spit function

【讨论】:

  • 注意:如果要对任意嵌套的 Clojure 值进行字符串化,最好使用pr-str 而不是str。如果将结果字符串直接馈送到流中,则应使用pr(或prn)而不是两步pr-str,后跟print.write
【解决方案2】:

试试这个:

(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* 更容易(除非您还想输出调试信息,在这种情况下可能会有点棘手)。

【讨论】:

    【解决方案3】:

    根据异常消息,行不是字符串、整数(字符)或整数数组的序列。

    【讨论】:

      猜你喜欢
      • 2020-05-15
      • 1970-01-01
      • 2014-06-29
      • 2011-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多