Почему, когда я использую программу 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)))))

Таким образом, вы можете отделить логику выбора ответа от логики вывода функции и логики рекурсии / завершения. в качестве бонуса вы избегаете повторений и улучшаете читабельность (ну, по моему мнению)

Другие вопросы по тегам