Почему, когда я использую программу printf, не посылаю строку на вывод, а когда я использую println, она делает?
Имея простую функцию в Clojure
(defn command []
(loop []
(let [input (read-line)
string-tokens (string/split input #" ")
tokens (map keyword string-tokens)
cmd (first tokens)]
(cond
;; explain the commands
(= cmd :help)(do
(printf "Usage:\nsearch <term>\nquit\n")
(recur)
)
;; break the loop
(= cmd :quit) (printf "bye bye")
;; do something
(= cmd :search) (do
(printf "Searching for %s...\n" (rest string-tokens))
(recur))
;; handle unknown input
:else (do
(println "Huh?")
(recur))
)
))
)
когда я использую println
для отправки строки на вывод это работает нормально, но когда я использую 'printf`, похоже, что строка хранится в буфере и печатается, когда я выхожу из программы, выбрав опцию:quit.
Я думаю, что это как-то связано с do
блок и рекурсия, но без этого я не могу использовать recur
как я получаю ошибку "могу только повторить от положения хвоста".
РЕДАКТИРОВАТЬ: Дело не в том, что моя программа не работает. Я нашел способ справиться с проблемой при первом использовании format
а потом println
(например. (println (format "Searching for %s...\n" (rest string-tokens)))
), но такое поведение странно для меня.
1 ответ
Так как println
звонки flush
функция, а printf
оленья кожа. Так что, если вы добавите (flush)
после каждого printf
позвони, будет работать.
(printf "Usage:\nsearch <term>\nquit\n")
(flush)
(recur)
Я хотел бы предложить вам переписать всю функцию следующим образом:
(defn command []
(loop []
(let [input (read-line)
string-tokens (clojure.string/split input #" ")
cmd (keyword (first string-tokens))
reply (case cmd
:help "Usage:\nsearch <term>\nquit"
:quit "bye bye"
:search (format "Searching for %s..." (rest string-tokens))
"Huh?")]
(println reply)
(when-not (= :quit cmd)
(recur)))))
Таким образом, вы можете отделить логику выбора ответа от логики вывода функции и логики рекурсии / завершения. в качестве бонуса вы избегаете повторений и улучшаете читабельность (ну, по моему мнению)