1、下面的圆括弧是否是需要的?
(x and y and (not z)) or ((not y) and x)
根据优先级,我们知道not 最大,and次之,or最小
x and y and not z or not y and x,该表达式也是先进行not z和not y操作,随后其结果与最近的and进行操作。所以,括弧是可以去掉的。
2、关于赋值
x = 10 --global one
local i = 1 -- local to the chunk
while i<=x do
local x = i*2 -- local to the while body
print(x) --> 2, 4, 6, 8, ...
i = i + 1
end
if i > 20 then
local x -- local to the "then" body
x = 20
print(x + 2)
else
print(x) --> 10 (the global one)
end
print(x) --> 10 (the global one)
--[[注意,如果在交互模式下上面的例子可能不能输出期望的结果,因为第二句local i=1
是一个完整的chunk,在交互模式下执行完这一句后,Lua将开始一个新的chunk,这样
第二句的i已经超出了他的有效范围。可以将这段代码放在do..end(相当于c/c++的{})
块中。]]--
--局部变量的访问速度快于全局变量
--我们给block划定一个明确的界限:do..end内的部分。当你想更好的控制局部变量的作用范围的时候这是很有用的。
do
local a2 = 2*a
local d = sqrt(b^2 - 4*a*c)
x1 = (-b + d)/a2
x2 = (-b - d)/a2
end -- scope of 'a2' and 'd' ends here
print(x1, x2)
3、两种类型的for循环
数值化的for和一般化的for
数值化的for和C中类型,这里主要说说一般化的for。
一般化的for是通过迭代器进行遍历的,如for k,v in pairs(t) do print(k,v) end
其中的t是一个table类型。k对应的是key,v存储的是key所对应的值。只要选择合适的迭代器进行进行对应的遍历。如,对应文件中行的遍历(io.lines),table的遍历(pairs),对于记录序列的遍历(ipairs),字符串的字符遍历(string.gmatch)等等。
例如:
days={"Sunday","Monday","Tuesday","Wednesday",
"Thursday","Friday","Saturday"}
revDays={["Sunday"]=1,["Monday"]=2,
["Tuesday"]=3,["Wednesday"]=4,
["Thursday"]=5,["Friday"]=6,
["Saturday"]=7}
x="Friday"
print(revDays[x])
--遍历后赋值
myreDays={}
for k,v in pairs(days) do
print("k"..k..".value:"..v)
myreDays[v]=k--其中key是1,2,3....value是Monday等
end
4、goto的使用
该用法其实是存在争议的,废弃或者使用,一直争议不断。goto主要用于模拟其他语言的结构。注意,goto是Lua 5.2.0才加进来的,早期版本是没有的。
其用法存在一定的限制性:
1)不允许跳转到一个块中去
2)不允许跳转到函数之外去
3)不允许跳入局部变量的作用域中
例子1:
goto quit
print('come on')
::quit::
print('quit')
这里输出 quit
例子2:
goto quit
local a
::quit::
print('quit')
这里,会出现语法错误(jumps into the scope of local 'a')。但是,有一个细节需要注意,我们先修改上面的例子:
goto quit
local a
::quit::
执行成功,没有语法错误。这是因为局部变量的作用域结束于变量定义的块的最后一个非 void 语句,而标签被认为是一个 void 语句,对于上面的例子来说,a 的作用域在 ::quit:: 之前就结束了,因此 goto quit 并没有跳入局部变量 a 的作用域中。
完整的如下:
while some_condition do
if some_other_condition then goto continue end
local var=something
<some code>
::continue::
end
上述代码中的local var是在end之前最后一个非void语句结束,而::continue::被视为一个void的语句,所以local var在<some code>中的某处已经结束了。这就不违背上述的原则,即不允许跳转到局部变量的作用域。
5、习题
1)为何Lua没有像C风格的语言那样提供else if而是直接提供一个elseif呢?这是由于在Lua中每个if都需要提供一个end,为避免过多的end的出现,而直接设计了elseif。
elseif which has the advantage to prevent from the need of lots of end
's statements.
代码如下:
-- why does Lua need elseif more than
-- other languages?
-- other languages (C, C++, Java) offer
-- a switch statement, which allow the
-- programmer to write code which should
-- be executed depending on what some
-- variable is
-- lua does not have this, however it
-- can be synthesised with an elseif
-- conditional like so:
cat = {name="Pinky", kind="cat"}
dog = {name="Watson", kind="dog"}
god = {name="The Lord", kind="god"}
function make_sound(e)
-- this is where one would traditionally
-- use a switch statement
if e.kind == "cat" then
print(e.name .. " says 'meow'.")
elseif e.kind == "dog" then
print(e.name .. " says 'woof'.")
elseif e.kind == "god" then
print(e.name .. " doesn't say anything.")
end
end
make_sound(cat)
make_sound(dog)
make_sound(god)
2) 、四种循环
<pre name="code" class="cpp">--loop1
function repeat_loop()
repeat
print('repeat loop')
until (false)
end
--loop2
function while_loop()
while (true) do
print('while loop')
end
end
--loop3
function for_loop()
for i = 1, math.huge do
print('For loop')
end
end
--loop4
function goto_loop()
do
::redo::
print('goto loop')
goto redo
end
end
print("which loop should be run?")
print(" 1. while loop")
print(" 2. for loop")
print(" 3. repeat-until loop")
print(" 4. goto loop")
loops = {while_loop, for_loop, repeat_loop, goto_loop}
selection = io.read("*n")
loops[selection]()