8

我正在通过这个网站学习 Lua 。我在教程的最开始并且正在尝试这个程序(输入一个数字x,它返回x!):

-- defines a factorial function
function fact (n)
  if n == 0 then
    return 1
  else
    return n * fact(n-1)
  end
end

print("enter a number:")
a = io.read("*number")  -- read a number
print(fact(a))

但是,当我运行它时,io.read似乎出现在提示之前。我在 Notepad++ 控制台中运行它,如下所示:

"C:\Program Files\Lua\5.1\lua.exe" "Path\To\factorial.lua"

输出(看起来)是空白的,但如果我输入一个数字,函数就会运行。

5
enter a number:
120

虽然这在这里不是什么大问题,但我只能想象在创建之前使用变量所带来的问题。那么,如何让这个程序在读取输入之前提示输入数字?

4

1 回答 1

13

发生的不是代码乱序运行,而是提示没有立即显示到终端。

在内部,您输出的任何内容都由操作系统存储在 IO 缓冲区中。定期清空缓冲区并将其内容显示在终端上(已刷新)。在大多数系统上,终端默认是行缓冲的,这意味着每次你写一个行尾字符时——它print()会自动执行——它会被刷新;但是,在某些系统上,它默认为完全缓冲,这意味着只有在填满时才会自动刷新。

有两种方法可以解决这个问题。如果要禁用或更改对文件的所有IO 操作的缓冲(并且出于这些目的,终端算作文件),可以使用该file:setvbuf()功能;特别是,io.output():setvbuf("no")将禁用标准输出的缓冲,这意味着您编写的任何内容都将立即显示。您还可以io.output():setvbuf("line")在支持但不是默认设置的系统上启用行缓冲。

另一种方法是手动刷新缓冲区,当您希望立即显示某些特定输出但又不想普遍禁用输出缓冲时,这很有用。您可以使用该函数执行此操作,该file:flush()函数会立即刷新缓冲区,例如:

-- no newline, so even on line-buffered systems this may not
-- display immediately
io.write("Enter a number: ")
-- so we force it to
io.flush()

请注意,io.write()andio.flush()只是 and 的便利函数io.output():write()io.output():flush()即它们获取当前输出文件,然后在它们上调用:write()or :flush()

(为什么要为缓冲而烦恼?因为它更快 - 将数据写入终端或文件很昂贵,并且写入一件大的东西比写入很多小东西要快。在大多数情况下,如果事情不这样做并不重要'不会在代码运行的那一刻就被写入,因此操作系统将要写入的数据保存在缓冲区中,然后在缓冲区填满时进行一次大写。)

于 2013-10-14T20:37:54.727 回答