Как читать строки из 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?
Ответы
Ответ 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.