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 循环中。

点赞
用户33252
用户33252
如果选择 == 1
然后 添加()
否则 如果选择 == 2
然后 保存()
否则 打印 "程序已经被终止\n谢谢!"
结束
2016-05-25 21:16:28
用户734069
用户734069

一般来说,如果你想在 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

你可以使用词法作用域,使表格中的函数能够访问局部变量,就像代码是内联书写的一样。

2016-05-27 22:18:24
用户7140551
用户7140551

如果你想把 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 函数,它可以成为你的项目中标准的函数来使用。

2016-12-09 08:39:22
用户7140551
用户7140551

下面是另一种使用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”部分。

2016-12-20 08:57:15
用户8133931
用户8133931

另外一个 switcher 的版本(不需要先将表格初始化为变量):

local case=2;
local result=({[1]="case1", [2]="case2", 3="case3"})[case];
print (result); --> case2
2017-06-08 22:08:35
用户6680332
用户6680332

尝试这个(点击此处在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)
2017-10-14 04:23:20
用户2550406
用户2550406

我在处理接受不同参数的函数时遇到了这个问题,其他答案无法很好地处理这个问题。

我用匿名函数解决了这个问题。

-- 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
2020-04-13 21:24:28
用户14448130
用户14448130

我使用以下代码:

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 ]]
2020-10-14 09:51:14
用户14723630
用户14723630

虽然创建一个以功能元素为索引的表格可能是最快的方法,但我认为我制作的这个解决方案在代码可读性方面更好:

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()
2020-11-28 08:45:34
用户10698755
用户10698755
```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,
}()
2021-09-29 21:53:22