Lua 中的无限循环错误

Infinite loop bug in Lua

我是这个平台的新手,我还在学习 Lua中的程序,所以,如果有新手错误,请见谅。

以下代码来自我项目中读取插入的函数之一 用户并验证它是否是“数字”类型的数据。如果, 循环将被打破,函数将 return 用户输入,否则, 程序将要求用户再次输入数据:

function bin.readnum(text)
    local insertion
    if text == nil then text = "Text: " end
    while (insertion == nil) do
        insertion = nil
        print(text)
        insertion = io.read("number")
        if insertion ~= nil then break end
    end
    return insertion
end

但是,如果用户输入了错误的数据(字符串),函数会打印 text 疯狂而不是要求用户重新输入数据。

io.read无法解析它获取到一个数字的数据时,它不会丢弃它,而是将它留在缓冲区中以供下一次调用它。这意味着在您的代码中,它不会让用户输入其他内容,而是会一直尝试永远解析相同的 non-number。要修复它,请在您的 if insertion ~= nil then 块中,在 break 之前执行 io.read() 以读取并丢弃整个无效行。

除了 Joseph Sible 所说的:

  • io.read("number") 是错误的:5.1 文档需要 "*n" 而 5.4 文档只需要 "n" 来阅读数字。它可能仍然有效,因为 Lua 只是在字符串中搜索字符。
  • 我建议将 insertion = io.read("number") 替换为 insertion = tonumber(assert(io.read(), "EOF")) - 这将读取一行并尝试将其解析为数字; assert 优雅地处理 nilio.read 编辑为 EOF 的 return。
  • 您不需要将 insertion 设置为 nil,如果读取的数字不是有效数字,后面的赋值已经这样做了。
  • 风格:考虑用真实性检查替换显式 nil 检查并删除 while 条件周围的括号。你不需要一个break,你可以立即return读取号码;最后,您甚至可以用尾递归替换整个循环。

总而言之,我将重写如下:

function bin.readnum(text)
    print(text or "Text: ")
    local num = tonumber(assert(io.read(), "EOF"))
    if num then return num end
    return bin.readnum(text)
end

或者使用 repeat-until 循环:

function bin.readnum(text)
    local num
    repeat
        print(text or "Text: ")
        num = tonumber(assert(io.read(), "EOF"))
    until num
    return num
end