【问题标题】:Clojure: *out* vs System/outClojure: *out* vs System/out
【发布时间】:2016-08-06 19:27:50
【问题描述】:

我正在尝试将我用 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))))

我很高兴我终于让它工作了,但我很困惑为什么第三个可以按照我想要的方式工作,而前两个却没有。为什么前两个立即阻塞?任何人都可以对此有所了解吗?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    the docs:

    *out* - 一个 java.io.Writer 对象,表示打印操作的标准输出。 默认为 System/out,包装在 OutputStreamWriter 中

    ...所以,你有一层包装。查看文档for that layer(已添加重点):

    每次调用 write() 方法都会导致对给定字符调用编码转换器。 生成的字节在写入底层输出流之前会累积在缓冲区中。 可以指定此缓冲区的大小,但默认情况下它对于大多数用途来说足够大。请注意,传递给 write() 方法的字符不会被缓冲。

    ...添加了重点。由于OutputStreamWriter有缓冲,需要调用.flush强制写入内容。

    【讨论】:

    • 我现在看到它被缓冲了,我需要先调用 .flush 。我没有意识到一个是流,另一个是作家。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-03
    • 1970-01-01
    • 2016-06-28
    • 2012-03-11
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多