Lua goto特性以及各种方便用途

原文连接

一、认识goto

goto是lua5.2以后加入的新特性,和其它语言中的goto用法相似;

goto说明符会将一段程序转换到一个label,一个label定义之后在整个代码块都是课件的,除了嵌套函数之外

用法如下:我们可以使用::gotoname_::来声明一个跳转的标志符,之后可以使用goto直接转到该行代码继续执行;

在lua中,一直会被抱怨没有continue关键字,使用goto就可以自己实现continue关键字;

例1:

for i=1,10 do
    if i%3 ~= 0 then goto workflow end
    print(i)
    ::workflow::
end

 

二、goto在lua中的广泛用途

上面提到的是最常用的一种用法,即使用goto来实现continue关键字的功能;下面会介绍使用goto实现的一些其它方便地用途;

1.简化错误处理流程

在continue关键字的实现过程中,我们并没有写goto跳转后的逻辑;但是,这里我们可以使用goto来到控制结构或函数末尾来做统一的逻辑处理;

如下示例:它用来处理一个字符串,函数内部先做判断如果是字符串类型就继续处理,然后返回;否则,就执行抛出错误;

这是一个比较简单的例子,它并没有体现出该用途的强大之处,如果有多个分支需要做统一的错误处理,才能更好的看到方便之处;

例2:

local function process(input_)
    if type(input_)~="string" then
        goto exception
    end
    print("processing...."..input_)
    do return end
    ::exception::
    print("luaexception input is not string "..input_)
end
process(100)
process("hello world")

 

2.嵌套break

在分支结构中的break,我们一次只能跳出当前的分支,当有多个循环结构而我们又想一次跳出多层循环时,就可以使用goto来完成;

例3:

for x=1,10 do
    for y=1,10 do
        for z=1,10 do
           if x^2+y^2==z^2 then
                print("found a pythagorean triple",x,y,z)
                goto done
           end 
        end
    end
end
::done::

 

3.嵌套continue

在上一个嵌套中,我们是跳出了所有的循环,从而只找到了一组勾股数;

当我们需要找到所有的勾股数,我们就需要调整goto label的位置,这里选择跳到第一层循环中;

并且改善了for循环的变量,y从x开始,z从y开始,减少轮询次数;

例4:

for x=1,10 do
    for y=x,10 do
        for z=y,10 do
           if x^2+y^2==z^2 then
                print("found a pythagorean triple",x,y,z)
                print("trying found next one...")
                goto done
           end 
        end
    end
    ::done::
end

 

4.perl风格的redo特性

这里把redo放置到for循环的开始位置,来实现redo功能;

例5:

for i=1,10 do
    local e=i
    ::redo::
    local flag=true
    for j=i,e do
        if j==i^2 then
            print(i.."^2==",j)
            flag=false
        end
    end
    if flag then
        e=e+1
        goto redo
    end
end

 

总结:goto label所放置的位置决定了其各种各样的特性;

posted @ 2022-05-20 16:40  青丝·旅人  阅读(742)  评论(0编辑  收藏  举报