为什么在Clojure中使用'print'打印的字符串只有在我使用println后才出现在控制台上?

4

我在Clojure中有以下代码:

(do
    (println "starting....")
    (sig! a 0)
    (sig! b 0)
    (future
      (Thread/sleep 4000)
      (println "switch 1")
      (sig! a 1)
      (sig! b 0)
      (Thread/sleep 4000)
      (println "switch 2")
      (sig! a 0)
      (sig! b 1)
      (Thread/sleep 4000)
      (println "switch 3")
      (sig! a 1)
      (sig! b 1)) nil))

我有一些监视器,它们监听原子a、b、s和c1的变化,并在变化时打印一些字符串。使用(print (str uid ":" @o "\n")或println版本。Clojure文档说printprintln应该表现完全相同,除了println中的换行符,但是我没有看到这一点。 当监视器使用println时,我立即看到字符串。当监视器使用print时,只有在下一个println被调用时才会看到输出。下面是使用println和使用print的输出结果。 使用print时,我只能看到最后一个println之前的值。
starting....
switch 1
a:1
s:1
switch 2
a:0
b:1
s:0
s:1
switch 3 

现在有println了。
starting....
switch 1
a:1

s:1

switch 2
a:0
b:1


s:0

s:1

switch 3
a:1

s:0

c1:1

正如您所看到的,这里打印出了观察者捕获到的变化。我使用的是Clojure 1.5版本。似乎print需要使用println才能将其内容刷新到控制台。

3个回答

6

仔细查看Clojure源代码code中的printlnprint后,发现二者的区别在于println调用prn,而print调用pr。在prn中,会调用functionnewline函数。然后检查是否为flush-on-new-line,如果是,则显式调用flush。因此,如果在字符串中使用任意数量的换行符("\n")调用print,不会刷新输出流,必须要么调用newline,要么直接调用flush


0

输出并不会立即显示在控制台上,直到它被刷新。通常,打印一个换行符是控制台刷新输出的默认信号。你可以通过调用大多数IO库中的刷新函数来强制执行这个操作。


我之前用的是(print (str uid ":" @o "\n")打印输出,虽然应该会有一个新行,但实际上并没有起作用。 - rileyfreeman
2
@rileyfreeman 你应该一开始就提到这个。请相应地更新你的问题。 - Frank Schmitt

0
根据Clojure文档,默认情况下每个换行符都会刷新输出。因此,您可能需要显式地刷新输出以获得所需的内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接