Lisp格式化和force-output

13
我不明白为什么这段代码在不同的实现中表现不同:
(format t "asdf")
(setq var (read))

在CLISP中,它的行为与预期相同,先打印提示符,然后读取输入,但在SBCL中,它是先读取,然后输出。我在网上看了一些资料并进行了更改:
(format t "asdf")
(force-output t)
(setq var (read))

这在CLISP中可以正常工作,但在SBCL中仍然会先读取,然后输出。我甚至尝试将其分开到另一个函数中:

(defun output (string)
   (format t string)
   (force-output t))
(output "asdf")
(setq var (read))

它仍然在读取,然后输出。我是不是没有正确使用force-output,还是这只是SBCL的特殊性?

1个回答

28

你需要使用FINISH-OUTPUT

在拥有缓冲输出流的系统中,一些输出会保留在输出缓冲区中,直到输出缓冲区满了(然后自动写入目标)或显式清空输出缓冲区。

Common Lisp 具有三个相关函数:

  • FINISH-OUTPUT,尝试确保所有输出都已完成,然后返回。

  • FORCE-OUTPUT,开始剩余的输出,但立即返回并且不等待所有输出完成。

  • CLEAR-OUTPUT,尝试删除任何待处理的输出。

此外,FORCE-OUTPUTFORMAT 中的 T 分别表示不同含义,这一点很不幸。

  • force-output / finish-output:其中 T 表示 *terminal-io*,而 NIL 表示 *standard-output*

  • FORMAT:其中 T 表示 *standard-output*

以下代码应该可以正常工作:

(format t "asdf")
(finish-output nil)   ;  note the NIL
(setq var (read))

另一个选择是根据 Practical Common Lisp 的建议,使用全局变量 *query-io* 而不是 t 或 nil。 - lindes

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