控制结构教程 |
|
if
语句
if
语句允许你根据条件运行不同的代码。
if condition then block elseif condition2 then block elseif condition3 then block else block end
if
和 elseif
部分按顺序检查,一旦其中一个条件为真,它就会运行其下的代码块并跳到末尾,忽略其后的任何其他 elseif
条件。如果没有任何条件匹配,则运行 else
代码块。最后,elseif
和 else
部分是可选的。
> n = 5 > if n > 5 then print("greater than 5") else print("less than 5") end less than 5 > n = 7 > if n > 5 then print("greater than 5") else print("less than 5") end greater than 5
一个更复杂的例子
> n = 12 > if n > 15 then >> print("the number is > 15") >> elseif n > 10 then >> print("the number is > 10") >> elseif n > 5 then >> print("the number is > 5") >> else >> print("the number is <= 5") >> end the number is > 10
注意,即使多个条件为真,也只打印了一条消息:这是因为一旦一个条件匹配,if
语句就会跳过检查其他条件。
while
循环
while condition do block end
这会在循环中反复运行代码块,但在每次迭代中,它首先检查条件,如果条件为假,则跳到 end
,退出循环。如果条件始终为假,则代码块永远不会运行。
> i = 1 > while i <= 10 do >> print(i) >> i = i + 1 >> end 1 2 3 4 5 6 7 8 9 10
repeat
循环
repeat block until condition
与 while
循环相同,只是条件被反转(在为真时退出循环),并且在第一次迭代后检查,因此代码保证至少运行一次。
> i = 5 > repeat >> print(i) >> i = i - 1 >> until i == 0 5 4 3 2 1
for
循环
for variable = start, stop, step do block end
运行代码块,variable
首先等于 start
,然后不断增加 step
量并再次运行代码块,直到它大于 stop
。step
可以省略,默认值为 1。
你也可以使 step
为负数,循环将在计数器变量小于停止值时停止。
> for i = 1, 5 do >> print(i) >> end 1 2 3 4 5 > for i = 1, 100, 8 do >> print(i) >> end 1 9 17 25 33 41 49 57 65 73 81 89 97 > for i = 3, -3, -1 do >> print(i) >> end 3 2 1 0 -1 -2 -3 > for i = 0, 1, 0.25 do >> print(i) >> end 0 0.25 0.5 0.75 1 > for i = 1, 3 do >> for j = 1, i do >> print(j) >> end >> end 1 1 2 1 2 3
还要记住,for
循环中的变量只在代码块内可见,循环退出后,它将不再包含最后一个值。
for
循环
for var1, var2, var3 in iterator do block end
for
循环的迭代器版本接受一个特殊的迭代器函数,并且可以有任意数量的变量。循环执行的操作、它需要的变量数量以及这些变量将被设置为的值取决于迭代器。
这主要适用于表,表还没有介绍,但这里有一个例子让你了解一下
> tbl = {"a", "b", "c"} > for key, value in ipairs(tbl) do >> print(key, value) >> end 1 a 2 b 3 c
这里,ipairs
是迭代器,它按顺序获取表中的编号条目。
break
语句
break
语句会导致 Lua 跳出当前循环。
> i = 3 > while true do -- infinite loop >> print(i) >> i = i + 1 >> if i > 6 then >> break >> end >> end 3 4 5 6
对于嵌套循环,break
只影响最内层的循环。
> for i = 1, 2 do >> while true do >> break >> end >> print(i) >> end 1 2
在循环之外使用 break
会导致语法错误。
> break stdin:1: <break> at line 1 not inside a loop
continue
语句的替代方案
许多其他语言都有一个 continue
语句,它会跳过当前循环的最内层迭代的剩余部分。在 Lua 5.2 中,可以使用 goto
来模仿这种行为。
> for i = 1, 10 do >> if i>3 and i<6 then goto continue end >> print(i) >> ::continue:: -- a name surrounded in :: :: is a goto label >> end 1 2 3 6 7 8 9 10
Lua 5.1 及更早版本没有 goto,但有其他解决方法。
> for i = 1, 10 do >> if not (i>3 and i<6) then >> print(i) >> end >> end 1 2 3 6 7 8 9 10 > for i = 1, 10 do repeat >> if i>3 and i<6 then break end >> print(i) >> until true end 1 2 3 6 7 8 9 10
条件不一定要是布尔值。实际上,任何值都是有效的条件:nil
和 false
使条件为假,其他任何值(包括 0)都使条件为真。
> if 5 then print("true") else print("false") end true > if 0 then print("true") else print("false") end true > if true then print("true") else print("false") end true > if {} then print("true") else print("false") end true > if "string" then print("true") else print("false") end true > if nil then print("true") else print("false") end false > if false then print("true") else print("false") end false
还有一些语言,变量赋值被认为是表达式(因此它可以用作子表达式),所以像这样的代码被写成
> i = 0 > while (i = i + 1) <= 10 do print(i) end stdin:1: ')' expected near '='
一些语言有一个三元运算符,它像 if/else 语句一样工作,但可以用作子表达式。如果条件为真,它会计算一个表达式,否则它会计算另一个表达式。
Lua 没有这样的运算符,但在许多情况下,可以使用 and
和 or
逻辑运算符来模仿它。这是因为两个原因:这些运算符如果仅从左侧结果就知道逻辑结果,就不会执行右侧表达式,而且它们直接返回其子表达式的结果,而不是将其转换为布尔值。
> = true and print("test") test nil > = false and print("test") -- 'and' is always false if one of the sides are false, don't bother running the other expression false > = true or print("test") -- 'or' is always true if one of the sides are true, don't bother running the other expression true > = false or print("test") test nil > = 8 or 5 8 > = true and "text" text
这可以用来创建一个简单的 if/else 表达式。
> condition = true > = condition and 2 or 4 2 > condition = false > = condition and 2 or 4 4 > = condition and print("a") or print("b") -- only the "false" branch is run, otherwise both a and b would be printed b nil
请记住,“and” 的优先级高于 “or”:如果条件为假,它会使 “and” 表达式放弃并返回 false。这将使 “or” 部分尝试其右侧表达式并返回其值。如果条件为真,“and” 将返回其右侧表达式。然后将其传递给 “or”,它会看到左侧结果是一个真条件,并直接返回它。
请注意,我们假设真分支的结果是一个充当真条件的值。这导致了一个问题:真分支不能计算为 nil
或 false
,因为那样的话假分支也会被执行,并且它的值会被返回。
> condition = true > = condition and false or true -- wrong result! true
这是因为整个“and”子表达式现在为假,导致“or”尝试运行其另一个子表达式。但是从假分支返回假值是可以的。事实上,如果你遇到像上面例子这样的情况,你可以简单地反转条件并交换分支的内容。
> condition = true > = not condition and true or false false
如果两个分支都必须返回一个充当假条件的值,那么有一种方法可以使用“or true”运算符。
> condition = 1 > =condition >= 1 and (print("condition >= 1") or true) or print("condition < 1") condition >= 1 true