Подтвердить что ты не робот

Как читать строки из stdin (* in *) в clojure

Я пишу свою первую программу clojure и хочу читать строки из stdin.

Когда я попробую это:

(doall (map #(println %) (line-seq *in*)))

Я получаю это исключение:

Exception in thread "main" java.lang.ClassCastException: clojure.lang.LineNumberingPushbackReader cannot be cast to java.io.BufferedReader (test.clj:0)

Я получаю те же результаты в версиях 1.0 и 1.1

Итак, как мне преобразовать *in* в seq, я могу продолжить итерацию? Я бы подумал, что это достаточно распространено, что *in* сам был бы итерабельным, но это тоже не сработает - если я попытаюсь использовать его напрямую, я получаю:

java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.LineNumberingPushbackReader (NO_SOURCE_FILE:0)

Кроме того, есть ли примеры выполнения общей обработки файлов в clojure?

4b9b3361

Ответ 1

Попробуйте обернуть *in* в java.io.BufferedReader. А также используйте doseq вместо doall, как указал devstopfix:

(doseq [ln (line-seq (java.io.BufferedReader. *in*))]
   (println ln))

Обратите внимание, что line-seq документируется, чтобы потребовать BufferedReader в качестве источника.

Ответ 2

Вероятно, вы должны использовать doseq вместо doall:

(doseq [line (line-seq (java.io.BufferedReader. *in*))] 
    (println line))

doall:

Прогуливается по последовательным соседям seq, сохраняет голову и возвращает ее, тем самым заставляя весь seq постоянно находиться в памяти.

doseq:

Не сохраняет главу последовательности. Возвращает ноль.

Ответ 3

Просто обратите внимание, что для тех, кто хочет читать только одну строку, есть функция read-line.