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
优雅地处理 nil
被 io.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
我是这个平台的新手,我还在学习 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
优雅地处理nil
被io.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