我试图将我用Java编写的小型控制台程序翻译成Clojure,但我在查找Clojure的标准*out*
var之间的区别时遇到了一些麻烦。 System/out
处的对象。我的印象是他们是同一件事,但在我的测试中,他们似乎有所不同。
在我的程序中,我提示用户输入一个数字,我希望提示和输入文本在同一行。在Java中,我使用System.out.print()
打印提示,然后扫描程序读取输入。
以下是我在Clojure中第一次尝试类似的事情。虽然print
函数似乎应该在read-line
之前触发,但它会立即阻塞输入并在混乱之后打印所有内容:
(defn inp1 []
(print "Enter your input: ")
(let [in (read-line)]
(println "Your input is: " in)))
以下是我的下一次尝试,使用*out*
。它遇到与上述功能相同的问题:
(defn inp2 []
(.print *out* "Enter input: ")
(let [i (read-line)]
(println "You entered: " i)))
在我的第三次尝试中,我终于通过直接使用System/out
来实现它:
(defn inp3 []
(let [o System/out]
(.print o "Enter input: ")
(let [i (read-line)]
(println "You entered: " i))))
我很高兴我终于得到了它的工作,但我很困惑,为什么第三个人在前两个人没有的时候按照我想要的方式工作。为什么前两个会立即阻止?任何人都可以对此有所了解吗?
答案 0 :(得分:8)
每the docs:
中
*out*
- 表示打印操作的标准输出的java.io.Writer对象。 默认为System / out,包含在OutputStreamWriter
...所以,你有一层包装。查看文档for that layer(强调添加):
每次调用write()方法都会导致在给定字符上调用编码转换器。 结果字节在写入底层输出流之前在缓冲区中累积。可以指定此缓冲区的大小,但默认情况下,它足够大,可用于大多数目的。请注意,传递给write()方法的字符不会被缓冲。
...重点补充。由于OutputStreamWriter
缓冲区,您需要调用.flush
来强制写入内容。