一、认识goto
goto是lua5.2以后加入的新特性,和其它语言中的goto用法相似;
goto说明符会将一段程序转换到一个label,一个label定义之后在整个代码块都是课件的,除了嵌套函数之外;
用法如下:我们可以使用::gotoname_::来声明一个跳转的标志符,之后可以使用goto直接转到该行代码继续执行;
在lua中,一直会被抱怨没有continue关键字,使用goto就可以自己实现continue关键字;
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来到控制结构或函数末尾来做统一的逻辑处理;
如下示例:它用来处理一个字符串,函数内部先做判断如果是字符串类型就继续处理,然后返回;否则,就执行抛出错误;
这是一个比较简单的例子,它并没有体现出该用途的强大之处,如果有多个分支需要做统一的错误处理,才能更好的看到方便之处;
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来完成;
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开始,减少轮询次数;
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功能;
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所放置的位置决定了其各种各样的特性;