我正在尝试自己创建一个脚本,这对于该领域的技术人员/销售人员是有益的。该产品系列有三种产品。但这些产品之间的唯一区别是尺寸。每种尺寸都包含安装它们所需的一定数量的支架。对于小型,只需要一个。对于媒体,两个。而对于大,四。
我希望我的脚本发出提示,询问用户每种类型产品的数量,因为任何安装都可以包含这些产品大小的任意数量。 (对不起,如果这令人困惑,但希望我的代码可以帮助解释更好。)我理想地喜欢这个脚本来获取所需的每个产品大小的数量,添加它们并吐出安装所需的总括号。现在,我无法弄清楚我是多么糟糕地抨击这段代码,因为我是编程新手。
请查看以下代码,我们非常感谢您提供任何帮助和/或建议。
function (t)
local t = {}
a,b = i,brackets
io.write ("Enter Total Number of Small Products")
answer = io.read()
if answer then
brackets = table.insert (t,#t+1,(answer * 1))
end
io.write ("Enter Total Number of Medium Products")
answer = io.read()
if answer then
brackets = table.insert (t,#t+1,(answer * 2))
end
io.write ("Enter Total Number of Large Products")
answer = io.read()
if answer then
brackets = table.insert (t,#t+1,(answer * 4))
end
local sum = 0
for i,brackets in ipairs (t) do
sum = sum + brackets
end
print (sum)
end
答案 0 :(得分:3)
我在这里看到几个问题:
您的代码全部包含在匿名函数中。虽然这在语法上是有效的,但您没有显示此函数被捕获并最终被调用。一个简单的脚本主要是在文件范围内编写的,尽管有时编写function main() --[[stuff happens]] end
是有意义的。特别是如果不是只写main()
而是编写类似pcall(main)
的内容来捕获并处理它所引发的任何错误。
声明您的匿名函数采用名为t
的参数。然后,该参数立即被名为t
的局部变量遮蔽,并且在函数内部无法访问。
您清楚地了解局部变量。那么为什么要使用名为a
,b
,i
,brackets
和answer
的全局变量?
变量a
和b
不会再次使用,而i
和brackets
会被for
创建的本地人所遮蔽稍后循环。
您了解函数,因此您应该注意到重复的代码会提示并读取值,并将其收集到函数中。
table.insert
未记录为返回值。
您正在使用t
作为数组,这是table.insert
已经知道的模式,因此#t+1
的第二个参数是多余的。如果遗漏,那就是table.insert
将值放在哪里。
您经常致电table.insert
,io.read
和io.write
。当前的最佳实践表明,将这些函数复制到局部变量将通过消除对全局符号表的访问(查找table
)然后第二次访问以查找函数来加速其访问。在文件范围的某处说local insert,read,write = table.insert,io.read,io.write
之类的东西就可以了。这样做功能范围将起作用,但会在每次调用函数时重新创建这些本地。
您正在使用t
作为数组,而像t[#t+1] = expression
这样的模式是一种非常常见的习惯用法,只需将项目附加到数组即可。它不仅比调用table.insert
更快(即使在定位值之后),但它也更清晰。
您似乎没有将零件尺寸的个别计数用于其他任何事情。所以根本没有必要保持阵列。当然,一个可能的崭露头角的功能是制作一份报告,总结每个大小的数量,括号的数量,然后包括总数。在这种情况下,保持一个表是有道理的。
在命令行中,您将发现流缓冲I / O的一些谜团。特别是,stdout
是行缓冲的(默认情况下在Linux和Windows上,几乎肯定也在Mac上),只要输出是终端而不是文件或管道。线路缓冲I / O不保证在流之间同步。因此,当您停下来阅读他们的答案时,您的提示可能实际上对用户不可见。解决此问题的一种方法是始终打印换行符,这将导致输出整行。另一种方法是在每次致电io.flush()
后致电io.write()
。
对错误处理进行一些考虑。不仅仅是io.write
失败会发生什么,但当用户回答“无”或“三”而不是预期的“0”或“3”时会发生什么。用户那样做。您的代码使用从字符串到数字的隐式转换,如果转换失败,则会出现 very 凌乱的错误消息。考虑显式调用tonumber()
,然后考虑在返回nil
时要执行的操作。即使明确地写(tonumber(answer) or 0) * 3
也比仅仅answer * 3
更好,因为它将所有非数字转换为数字0.更好的是引导用户进行有效输入。
答案 1 :(得分:2)
您发布的代码存在许多问题。如果您所拥有的唯一要求是您所声明的那些,则以下脚本使用函数来执行输入和总和的计算,结果将返回。
local function GetSum()
local sum = 0
local answer
io.write ("Enter Total Number of Small Products: ")
answer = io.read()
if answer then
sum = sum + tonumber( answer )
end
io.write ("Enter Total Number of Medium Products: ")
answer = io.read()
if answer then
sum = sum + 2 * tonumber( answer )
end
io.write ("Enter Total Number of Large Products: ")
answer = io.read()
if answer then
sum = sum + 4 * tonumber( answer )
end
return sum
end
print( GetSum() )
注意:对tonumber
函数的调用不是必需的,因为Lua将answer
中的字符串强制转换为该上下文中的数字,但是在更大的应用程序中,显式是有用的,以便读者可以清楚地发现正在进行类型转换。