Lua 语言中 switch 语句的替代方案是什么?
我有一些 C++ 代码,我想知道如何编写一些代码来替换 Lua 中的 switch 语句,因为我遇到了很多问题,所以我需要使用这个语句。
int choice;
// 循环
{
cout<< "\n >>> The General Menu <<< \n";
cout << endl;
cout<< " press (1) to Add "<<endl;
cout<< " press (2) to Save "<<endl;
cout<< " press (3) to Quit " << endl;
cout<< endl;
cout<< "Enter your choice please (1/2/3): ";
cin>>choice;
switch(choice)
{
case 1:
add();
break;
case 2:
save();
break;
default:
cout<<" The program has been terminated "<<endl;
cout<<" Thank you! \n";
}
} while (choice != 3);
} 这个语句被用在一个 do..while 循环中。
一般来说,如果你想在 Lua 中使用 switch 语句,你应该构建一个表格。对于你的简单情况,即 choice 可以是 1、2 或失败,一个简单的 if 语句就足够了。对于更复杂的情况,应该使用一张函数表:
local c_tbl =
{
[1] = add,
[2] = save,
}
local func = c_tbl[choice]
if(func) then
func()
else
print "程序已经终止。"
print "谢谢!";
end
你可以使用词法作用域,使表格中的函数能够访问局部变量,就像代码是内联书写的一样。
如果你想把 switch 作为一个可调用的函数使用,你可以借助回调函数的特性:
(下面的例子是一个基于变量类型的 switch 语句,但你可以把表格的索引改成你想要进行测试的任何内容。只要将 switch 函数的返回语句改变,不测试类型(case)即可)。
(实际上,这是一种懒觉表查找,类似于 Python 的字典特性,但每个元素都是一个函数)。
#!/usr/bin/lua
-- 回调 switch 语句:
local function switch(a, case)
-- 使用本地变量而不是 function(a) 在每个 case 上:
local value = a
-- Cases 列表:
local switchcase = {}
-- Cases:
switchcase["string"] = function()
return (tostring(value) .. " 是一个字符串")
end
switchcase["number"] = function()
return tostring(value .. " 是一个数字")
end
switchcase["boolean"] = function()
return (tostring(avalue) .. " 是一个布尔值")
end
return switchcase[type(case)](a)
end
local value = 5
print(switch(value,value)) --> 5 是一个数字
local value = "test"
print(switch(value,value)) --> test 是一个字符串
local value = true
print(switch(value,value)) --> true 是一个布尔值
我不知道这段代码与上面给出的两个答案相比性能如何,但使用本地变量应该足够快速地重复使用。如果在全局范围内创建 switch 函数,它可以成为你的项目中标准的函数来使用。
下面是另一种使用loadstring()和表查找的有趣方法。
switch = function(cases,args)
if (cases[args] == nil) then return args else return assert(loadstring ('return ' .. cases[args]))() end
end
local case = 2
local result = switch({
[1] = "2^" .. case,
[2] = string.format("2^%i",case),
[3] = tostring(2^case)
},
case
)
print(result) --> 4
这种方法有些危险,因为loadstring()类似于Python中的eval()函数。
我发现在Lua维基提供的示例中,在每种情况下都写“function(x)”很丑陋。这是一种简洁的方法。
“默认”情况是函数的“return args”部分。
另外一个 switcher 的版本(不需要先将表格初始化为变量):
local case=2;
local result=({[1]="case1", [2]="case2", 3="case3"})[case];
print (result); --> case2
尝试这个(点击此处在Lua编译器中运行脚本),希望代码是自解释的 ;-)并且类似于相同的伪代码格式..!!
print("请输入你的选择:")
mychoice = io.read()
switch = function (choice)
-- 接受数字或字符串
choice = choice and tonumber(choice) or choice -- 如果是数字或字符串,则返回数字。
-- 定义您的条件
case =
{
[1] = function ( ) -- 第1种情况:
print("你的选择是数字1 ") -- 代码块
end, -- 断点语句
add = function ( ) -- “add”情况:
print("你的选择是字符串add ") -- 代码块
end, -- 断点语句
['+'] = function ( ) -- “+”情况:
print("你的选择是字符+ ") -- 代码块
end, -- 断点语句
default = function ( ) -- 默认的情况
print("你的选择与指定情况中的任何一个都不匹配")
end, --不能在这里排除结束 :-P
}
-- 执行部分
if case[choice] then
case[choice]()
else
case["default"]()
end
end
-- 现在你可以像常规函数一样使用它。Tadaaa..!!
switch(mychoice)
我在处理接受不同参数的函数时遇到了这个问题,其他答案无法很好地处理这个问题。
我用匿名函数解决了这个问题。
-- call the relevant execution based on its opcode
local instructions = {
[01] = function () self:perform_add(table.unpack(valargs)) end,
[02] = function () self:perform_multiply(table.unpack(valargs)) end,
[03] = function () self:perform_store_input(outputargs[1]) end,
[04] = function () self:perform_output(valargs[1]) end,
[05] = function () self:perform_jnz(table.unpack(valargs)) end,
[06] = function () self:perform_jz(table.unpack(valargs)) end,
[07] = function () self:perform_less_than(table.unpack(valargs)) end,
[08] = function () self:perform_equals(table.unpack(valargs)) end,
[99] = function () self:perform_exit() end,
}
local instr = instructions[opcode]
if (instr) then
instr()
else
print("No instruction for opcode " .. opcode)
end
我想在不同的 switch cases 中执行的动作都在一个表中定义为匿名函数。所使用的键(例如这里的 08)是我们要切换的变量(此处是 opcode)可能具有的值。 switch 语句的默认情况在我的 else 语句中发生。没有要求类似 break 的东西 - 但是如果您想让一个 case 继续下一个,您必须明确调用它。
回复评论要求澄清:
你是对的,这个例子不完整。您可以在此处找到我的用法here,在那里我参加了2019年的圣诞节。我可以尝试回答您的问题,但是我以前从未接触过lua,也从未再次接触过。 valargs 是一个参数表,因为此处的不同函数采用不同数量的参数。但这并不一定与问题相关。基本上,我只是在这里调用函数。
在我的示例中,self 存在是因为我在 local 上定义了函数(并进行了一些奇怪的更改,如这里所述)。相关代码部分:
-- a "class"
local IntComputer = {}
function IntComputer:perform_exit()
self.program_ended = true
end
function IntComputer:perform_add(a, b, target)
print(" " .. a .. " + " .. b .. " => " .. target)
self:set_value(target, a+b)
end
我使用以下代码:
while true do
local tmpswitch1 = exp ; --[[ switch <exp> do ]]
if tmpswitch1 == exp1 then --[[ case <exp1> : ]]
-- 做一些事情
break
end ;
if tmpswitch1 == exp2 then --[[ case <exp2> : ]]
-- 做一些事情
break
end ;
--[[ default : ]]
-- 做一些事情
break ;
end --[[ switch tmpswitch1 ]]
虽然创建一个以功能元素为索引的表格可能是最快的方法,但我认为我制作的这个解决方案在代码可读性方面更好:
function switch(element)
local Table = {
["Value"] = element,
["DefaultFunction"] = nil,
["Functions"] = {}
}
-- 给Table添加case方法
Table.case = function(testElement, callback)
Table.Functions[testElement] = callback
return Table
end
-- 给Table添加default方法
Table.default = function(callback)
Table.DefaultFunction = callback
return Table
end
-- 给Table添加process方法
Table.process = function()
local Case = Table.Functions[Table.Value]
if Case then
Case()
elseif Table.DefaultFunction then
Table.DefaultFunction()
end
end
return Table
end
例如用法:
-- 调用switch函数,并以Player:GetName()返回值作为参数
switch(Player:GetName())
-- 对testElement赋值"Kate",将callback设置为输出"This player's name rhymes with Fate"
.case("Kate", function() print("This player's name rhymes with Fate")end)
-- 对testElement赋值"Tod",将callback设置为输出"This player's name rhymes with Cod"
.case("Tod", function() print("This player's name rhymes with Cod") end)
-- 设置默认的callback为输出"This player's name is not Kate or Tod"
.default(function() print("This player's name is not Kate or Tod") end)
-- 调用process方法执行所有callback
.process()
```lua
function case(i,d) return function(t) return t[i] or d end end
x='two'
r=case(x) {
one=1,
two=2,
three=3,
}
case(r,function() print "default" end) {
[1]=function() print "one" end,
[2]=function() print "two" end,
[3]=function() print "three" end,
}()
将上面的 Lua 代码翻译成中文并且保留原本的 markdown 格式:
```lua
-- 定义 case 函数
function case(i, d)
return function(t)
return t[i] or d
end
end
-- 定义变量 x
x = 'two'
-- 使用 case 函数,取得 table r 中 x 所对应的 value
r = case(x) {
one = 1,
two = 2,
three = 3,
}
-- 根据 r 的值,选择执行相应的函数
case(r, function() print("default") end) {
[1] = function() print("one") end,
[2] = function() print("two") end,
[3] = function() print("three") end,
}()
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
如果选择 == 1 然后 添加() 否则 如果选择 == 2 然后 保存() 否则 打印 "程序已经被终止\n谢谢!" 结束