【问题标题】:Clojure - Side Effects Happening Out Of OrderClojure - 无序发生的副作用
【发布时间】:2008-12-23 03:02:10
【问题描述】:

在涉足 Clojure 时,我编写了一个非常基本的程序来回显用户在其中输入的任何内容。然而,它并没有以我认为自然的方式运行。代码如下:

(defn goo []
  (print "echo> ")
  (def resp (read-line))
  (print resp)
)

我希望代码像这样运行(我输入foo 作为read-line 的输入):

user=> (goo)
echo> foo
foonil

但是,echo 和 read-line 被切换了:

user=> (goo)
foo
echo> foonil

为什么会这样?有没有我遗漏的微妙之处?

编辑:根据乔的回答,更新后的正确解决方案是:

(defn goo []
  (print "echo> ")
  (flush)
  (def resp (read-line))
  (print resp)
  (flush)
)

此外,如果您使用 println 而不是 print,则不需要刷新。

【问题讨论】:

    标签: clojure


    【解决方案1】:

    我对 clojure 一无所知,但这听起来像是缓冲区没有被刷新的情况。弄清楚如何在打印后冲洗标准。 println 函数可能会在每行的末尾刷新。试试:

    (defn goo []
      (print "echo> ")
      (flush )
      (def resp (read-line))
      (print resp)
    )
    

    【讨论】:

    • 做到了!打印后添加(冲洗)。感谢您的快速回复!
    • 酷。现在我有一个我不知道的语言的检查答案。 :-) 很高兴我能帮上忙。
    • 好手艺!出于对知道 Clojure 但不了解标准输出缓冲区内部工作原理的人的好奇……为什么会出现这个问题?排序可以在缓冲区内更改似乎很奇怪.....
    • 我不知道 Closure 所以我只能猜测。内部缓冲区用于将文件系统的直接 I/O 量保持在较低水平。但是当 I/O 很慢并且没有人使用线程时,选择了这种设计用于 I/O。在面向在线的终端上,数据仅在您按 Enter 时发送到主机系统。这允许打字员在将行缓冲区发送到主机系统之前对其进行编辑。人们不再使用终端,因此这种知识逐渐消失。 (上周遇到一位从未见过 5.25 英寸软盘的程序员......)
    【解决方案2】:

    另外,请不要使用“def”,除非您真的非常想定义一个全局变量。改用“让”:

    (defn goo []
      (print "echo> ")
      (flush)
      (let [resp (read-line)]
        (print resp)
        (flush)))
    

    或者,更短

    (defn goo []
      (print "echo> ")
      (flush)
      (print (read-line))
      (flush))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-02
      • 2019-03-05
      • 2014-03-29
      • 2015-11-01
      • 2020-12-31
      • 2016-12-11
      • 1970-01-01
      相关资源
      最近更新 更多