2011-12-19 16 views
6

Clojure'da bir dosyaya yazmak için bu işlevi kullanıyorum.Clojure'da bir dosyaya yazma


(defn writelines [file-path lines] 
    (with-open [wtr (clojure.java.io/writer file-path)] 
    (doseq [line lines] (.write wtr line)))) 

Ama bu her zaman bu hatayı oluşturur:

IllegalArgumentException No matching method found: write for 
class java.io.BufferedWriter in 
clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:79) 

yanlış burada ne yapıyorum?

+0

Netlik için sorunuza örnek bir işlev çağrısı ekleyebilir misiniz? Opqdonut'un cevabını doğrulamak olasıdır. – Gert

+0

Sorunuza bir cevap değil, ancak bu bağlamda ilginç olabilir: http://stackoverflow.com/questions/7756909/in-clojure-1-3-how-to-read-and-write-a-file/ 7757674 # 7757674 –

cevap

17

Öncelikle, fonksiyon birçok girişler için sadece iyi çalışır:

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 

Ancak, garip bir şey geçmesine çalıştığınızda size hatayı açıklayan olsun:

user=> (writelines "quux" [#{1}]) 
IllegalArgumentException No matching method found: write for class java.io.BufferedWriter clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:79) 

Bu hata BufferedWriter'un write'un birden fazla aşırı yüklenmiş sürümüne sahip olması ve clojure'nin hangisinin arayacağını bilmemesidir. Bu durumda çelişen olanlar write(char[]) ve write(String)'dur. Dizgiler ("a") ve tamsayılar (1) clojure gibi girdiler, yöntemin String sürümünü çağırmayı biliyordu, ancak başka bir şeyle (örneğin, bir clojure seti, #{1}) clojure karar veremedi.

writelines numaralı girdilerin gerçekten String s olduğunu doğrulamak ya da str işlevini kullanarak bunları dizgilemek?

Ayrıca, spit function'a bakın.

+0

Not: Eğer keyfi şekilde iç içe geçmiş bir Clojure değerini dizgelemek istiyorsanız, 'str' yerine' pr-str 'kullanmak daha iyidir. Sonuçtaki dize doğrudan bir akışa beslenirse, iki adımlı 'pr-str' yerine' print' veya '.write' yerine' pr' (veya 'prn'') kullanılmalıdır. – raek

0

Kural dışı durum iletisine göre, satır dizeleri, ints (chars) veya int dizileri değil.

1

bu deneyin: BufferedWriter belgelerine bakacak olursak

(defn writelines [file-path lines] 
    (with-open [wtr (clojure.java.io/writer file-path)] 
    (binding [*out* wtr] 
     (doseq [line lines] (print wtr line))))) 

Eğer write arayarak şekline geri hiçbir karşılık gelen yöntemini göreceksiniz (hoppala, bana aptal kalıtsal yöntemleri cevapsız!). *out*'a bağlanmak her şeyden daha kolay, sanırım (hata ayıklama bilgisini de almak istemiyorsanız, bu durumda biraz daha zor olabilir). Her şeyden