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所放置的位置决定了其各种各样的特性;