在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`时,看起来字符串保存在缓冲区中并在我通过选择退出程序时打印:退出选项。< / p>
我认为这与do
阻止和递归有关,但没有它我不能使用recur
因为我收到“只能从尾部位置重现”错误。
format
然后println
(例如(println (format "Searching for %s...\n" (rest string-tokens)))
)找到了解决问题的方法,但这种行为对我来说很奇怪。
答案 0 :(得分:2)
因为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)))))
我建议你用以下方式重写整个功能:
{{1}}
因此您可以将回复选择逻辑与函数的输出和递归/终止逻辑分开。作为奖励,你可以避免重复,并提高可读性(好吧,imo)