八、补充知识
8.1 局部变量和代码块
对于局部代码块的声明,如
local i = 1
这个在交互模式中不能正常读到i的值。因为在交互模式中,每一行代码就是一个代码段(除非不是一条完整的命令),要想解决这个问题,可以用do-end,如
> do
>> local i = 1
>> print(i+1)
>> end
2
>
do-end还可以用于需要更好的控制某些局部变量的生效范围时,如
local a,b,c = 1,2,1
local x1,x2
do
local a2=2*a
local d = (b^2 - 4*a*c)^(1/2)
x1=(-b+d)/a2
x2=(-b-d)/a2
end
print(x1,x2)
尽可能的使用局部变量是一种良好的编程风格。
Lua语言有一种常见的用法
local foo = foo
将全局变量foo赋值给声明的局部变量foo,这个用法的好处在于
- 在需要提高对全局变量foo的访问速度时
- 当其他函数改变了全局变量foo的值,而代码段又需要保留foo的原始值时
8.2 控制结构
控制结构的条件表达式的结果可以是任何值。请记住,Lua语言将所有不是false和nil的值当做真,特别的,Lua语言将0和空字符串也当做真
8.2.1 if then end
由于Lua语言不支持switch语句,所以一下的if-elseif-then-end语句比较常见
if op == "+" then
r = a+b
elseif op == "-" then
r = a-b
elseif op == "*" then
r = a*b
elseif op == "/" then
r = a/b
else
error('Invalid operation')
end
8.2.2 while
都好简单,就看个语法吧
local i = 1
while a[i] do
print(a[i])
i = i+1
end
8.2.3 repeat
repeat-until的特殊之处在于,至少会执行一次,而且在Lua语言中,循环体内声明的局部变量的作用域包括测试条件:
--使用Newton-Raphson法计算'x'的平方根
x = 100
local sqr = x/2
repeat
sqr = (sqr+x/sqr)/2
local error = math.abs(sqr^2 - x)
print(error)
until error < x/10000 --局部变量'error'此时仍然可见
8.2.3 数值型for和泛型for
数值型for
for var = exp1,exp2,exp3 do --exp1初始值,exp2是最大值,exp3是步长
something
end
for i = 1,10,2 do --i是局部变量
print(i)
end
print(i) --i打印的是空值
for j = 1,math.huge do --用math.huge就是循环没上限,默认步长是1
print(j)
end
泛型for
for i,v in ipairs(table_name) do --i和v也都是局部变量
print(i,v)
end
for k,v in pairs(table_name) do
print(k,v)
end
for cmd_list in io.lines(file_path) do
print(cmd_list)
end
8.2 break、return和goto
所有函数的最后都有一个隐藏的return,所以我们不需要在每一个没有返还值的函数最后书写return语句。
goto是Lua 5.2添加进去的;goto后面紧跟标签名,标签名可以是任意有效的标志符,标签的语法 ::name::
在使用goto语句跳转时,Lua语言设置了一些限制条件:
- 标签遵循常见的可见性规则,因此不能直接跳转到一个代码块中的标签
- goto不能跳转到函数外
- goto不能跳转到局部变量的作用域
比如,Lua语言没有的continue、redo和局部错误处理等,用goto都可以实现,如下:
while some_condition do
::redo::
if some_other_condition then
goto continue
elseif yet_another_condition then
goto redo
end
some code
::continue::
end
Lua语言规范中一个很有用的细节是,局部变量的作用域终止于声明变量的代码块中的最后一个有效(non-void)语句处,标签被认为是无效(void)语句,看下列代码:
while some_condition do
if some_other_condition then
goto continue
end
local var = something
some code
::continue::
end
var的作用域终止于some code
我这边玩了下io.read()函数
> do
>> x = io.read(1)
>> print('haha' ..x)
>> end
juudei
hahaj
用goto写一个状态机
::s1:: do
local c = io.read(1)
if c == '0' then goto s2
elseif c == nil then print 'ok'; return
else goto s1
end
end
::s2:: do
local c = io.read(1)
if c == '0' then goto s1
elseif c == nil then print 'not ok'; return
else goto s2
end
end
goto s1
网友评论