(读取行)在执行prinln之前执行

时间:2019-04-10 09:09:02

标签: clojure

(do
  (print "Enter name: ")
  (let [name (read-line)]
    (println "Hello " name)))

提示输入我的名字,然后执行printprintln语句,如下所示:

Enter name: Hello  stuart
=> nil

我尝试了(flush)

(do
  (print "Enter name: ")
  (flush)
  (let [name (read-line)]
    (println "Hello " name)))

但是同样的事情发生了,它总是先做(读取行)!

我也尝试过

(doall (
  (print "Enter name: ")
  (flush)
  (let [name (read-line)]
    (println "Hello " name))))

但是这再次提示您先输入名称,然后再引发异常:(

我在这里缺少明显的东西吗?

:注意:这是通过repl运行的。

如果我尝试使用以下内容创建应用程序

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (do
  (print "Enter your name: ")
  (flush)
  (let [s (read-line)]
    (println "You entered " s))))

(-main)

并运行它,而不是通过repl运行,除非它两次运行都可以正常运行!

Enter your name: stuart
You entered  stuart
Enter your name: stuart
You entered  stuart

Process finished with exit code 0

如果我移除了(flush),它将无法正常工作,但仍会执行两次!

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (print "Enter your name: ")
  (let [s (read-line)]
    (println "You entered " s)))

hfghfgh
Enter your name: You entered  hfghfgh
fghfgh
Enter your name: You entered  fghfgh

Process finished with exit code 0

发生了什么事!

这都是用lein

1 个答案:

答案 0 :(得分:2)

我要在这里走一走,因为我很快就要开始工作。

您是否通过IntelliJ + Cursive中的REPL运行它?如果是这样,则REPL配置之一(会生成一个弹出窗口以输入内容的配置)不能很好地为stdin提供输入。我不确定为什么,但是我已经处理了一段时间。在“编辑配置...”中有两个配置设置可供选择:“ nREPL”(我称为“完整”)和“ clojure.main”(我称为“简单”)。

如果我用stdin做任何事情,我会使用Simple,因为Full具有您描述的奇怪行为。从一开始,Simple的加载速度也会更快,但是不允许在不终止整个REPL的情况下执行诸如终止当前正在运行的任务之类的美好事情。

要“修复”它,请单击右上角附近的运行配置下拉菜单,单击“编辑配置”,左上角的“ +”,“ Clojure REPL”,“本地”,然后使用“ clojure.main” “运行哪种REPL类型:”下的“”选项。给它起一个“简单”之类的名称,或将其与您使用的其他配置区分开来。


正如@akond所提到的,如果您使用lein run或类似的机制为您调用-main,那么您将使事情运行两次。无论如何,在脚本中对-main进行顶级调用并不理想。它将在加载文件的任何时间强制运行整个脚本,如果您使用REPL进行开发,则该脚本经常会运行。最好在您明确希望它运行时在REPL中调用-main