ok,我们上一篇中已经了解一大堆玩意了,不过还是冰山一角,那么今天学学循环和if else语句吧 如果你学过其他语言,绝对 对循环有回家一样的亲切感,同样的,什么for循环,while循环,do …while循环在lua中也是一样的
而且if else你绝对老熟悉了
前面我们挖了一个坑(就是数组的遍历部分),接下来可以讲讲了
没学过的小伙伴可以看一下定义:
循环是程序中用于重复执行 某段代码(循环体)的控制结构,它包含一个条件判断 和要重复执行的循环体 ,直到条件不再满足时终止。
一组被重复执行的语句称之为循环体
我们可以画一个图
while循环 格式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 while 判断条件 do 循环体 改变条件 end while (判断条件) do 循环体 改变条件 end while 判断条件do 循环体 改变条件 end while (判断条件) do 循环体 改变条件 end
你可以把do…end想像为其他语言中的花括号{ },而判断条件里的括号可写可不写 这一点和python和gdscript很像
这里我用C#里的你可以对比一下
1 2 3 4 5 6 while (a < 20 ) { Console.WriteLine("a 的值: {0}" , a); a++; }
while 循环语句在判断条件为 true 时会重复执行循环体语句
1 2 3 4 5 6 7 8 9 local cookies = 20 while (cookies > 0 ) do print ("爱丽丝拿了一块饼干 🍪" ) cookies = cookies - 1 print ("罐子里还剩" ..cookies.."块" ) end print ("罐子空了,爱丽丝溜了!" )
对了,while还可以制造无限循环
1 2 3 4 while ( true )do print ("爱丽丝一直偷吃饼干" ) end
什么,你说while无限循环除了让电脑死机还有什么用,请看Unity的Update和FixedUpdate方法的本质:
可以看到,这两个unity脚本离不开的核心函数都是无限调用,估计 love2d 中也有类似的函数
for 循环 for 循环语句可以重复执行指定语句,重复次数可在 for 语句中控制,刚才的while循环的循环次数是不受控制的,只有不满足条件时才会跳出循环
对了,lua里面没有a++,++a,a–,–a这种写法, 或者a+=1 a-=1这种写法, 只能写成a=a+1 或者a=a-1
格式:
1 2 3 for 局部变量名=循环起始值,循环结束值,循环步长 do 循环体 end
同样可以参考一下C#的
1 2 3 4 for (int a = 10 ; a < 20 ; a++){ Console.WriteLine("a 的值: {0}" ,a); }
我们用代码来讲更好理解一些
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 local cookies = 20 for i = 1 , cookies do print ("爱丽丝第" .. i .. "次拿饼干 🍪" ) cookies = cookies - 1 end if cookies ~= 0 then print ("罐子里还有" .. cookies .. "个饼干,爱丽丝还能继续吃!!!" ) else print ("罐子空了,爱丽丝溜了,小桃小绿回来后很生气!!!" ) end
我们可以改一下条件
1 2 3 4 5 6 7 8 9 10 11 12 13 local cookies = 20 for i = 6 , cookies do print ("爱丽丝第" .. i .. "次拿饼干 🍪" ) cookies = cookies - 1 end if cookies ~= 0 then print ("罐子里还有" .. cookies .. "个饼干,爱丽丝还能继续吃!!!" ) else print ("罐子空了,爱丽丝溜了,小桃小绿回来后很生气!!!" ) end
我们还可以验证一下循环步长的作用,这个不写的话默认为 1
1 2 3 4 5 6 7 8 9 10 11 12 13 local cookies = 20 for i = 1 , cookies, 2 do print ("爱丽丝第" .. i .. "次拿饼干 🍪" ) cookies = cookies - 1 end if cookies ~= 0 then print ("罐子里还有" .. cookies .. "个饼干,爱丽丝还能继续吃!!!" ) else print ("罐子空了,爱丽丝溜了,小桃小绿回来后很生气!!!" ) end
还可以将饼干减少的逻辑封装到函数里
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 local cookies = 20 function EatCookies (number) number = number - 1 return number end for i = 1 , cookies do print ("爱丽丝第" .. i .. "次拿饼干 🍪" ) cookies = EatCookies(cookies) end if cookies ~= 0 then print ("罐子里还有" .. cookies .. "个饼干,爱丽丝还能继续吃!!!" ) else print ("罐子空了,爱丽丝溜了,小桃小绿回来后很生气!!!" ) end
好了,接下来把之前挖的坑填上———表的遍历学过其他语言的数组的小伙伴通常会用for循环来遍历数组,我们lua也是一般使用for循环
这里的lua的遍历分为三种: ipairs遍历 第一种: ``ipairs —— 顺序数组遍历
格式(缩写版,推荐):
1 2 3 4 5 local 表名 = {....}for i, v in ipairs (表名) do print (i, v) end
完整版
1 2 3 4 5 local 表名 = {....}for index, value in ipairs (表名) do print (index, value) end
这种遍历属于有序遍历,即从前到后, i 的值默认为1 不可更改
而且遍历的时候如果遇到 nil(即遇到空值断层) 后会停止遍历,而且遍历时遇到键值对会自动跳过
i 和 v 是循环过程中“每一轮自动赋值的两个局部变量”
i = 当前元素的索引(key)
v = 当前元素的值(value)
1 2 3 4 5 6 7 8 9 10 11 local cookies = { "奶龙" , "贝利亚" , "丰川祥子" , "千早爱音" , "橘雪莉" }print ("唐朝最唐生物排名:" )for i, v in ipairs (cookies) do print (i, v) end for i, v in ipairs (cookies) do print (i .. v) end
pairs遍历 第二种: ``pairs —— 通用遍历
这个格式和 ipairs一样:
1 2 3 4 5 local 表名 = {....}for i, v in pairs (表名) do print (i, v) end
完整版
1 2 3 4 5 local 表名 = {....}for index, value in ipairs (表名) do print (index, value) end
这种可以遍历 table 中所有键值对 (无论是数组还是字典),但是遍历的顺序是无序的,而且不同于ipairs的是,pairs遇到nil时不会停止,而是直接跳过索引对应的空值
可以看到这是没有顺序的遍历
for循环遍历 这个其实也可以采用原生的for循环遍历,不过这个for循环只支持数组,不支持字典
和其他语言中用for遍历数组的方式是差不多的
格式:
1 2 3 4 5 local 表名 = {....}for i=1 , #表名 do print (i, 表名[i]) end
其实就是for循环,这里就用一个例子来解释吧,我们可以变相来遍历字典实现顺序遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 local cookies = { order = { "tang_01" , "tang_02" , "tang_03" , "tang_04" , "tang_05" , }, data = { tang_01 = "奶龙" , tang_02 = "贝利亚" , tang_03 = "丰川祥子" , tang_04 = "千早爱音" , tang_05 = "橘雪莉" } } for i = 1 , #cookies.order do local key = cookies.order[i] print (i, cookies.data[key]) end
repeat … until 循环 这个非常有意思
学过其他语言比如C C++ C#这些绝对知道 do … while循环
但是我们可以看一下 do … while循环的特性
1 2 3 4 5 6 do { } while (condition);
但是看看我们的Lua就是相反的
1 2 3 4 5 6 repeat until condition
我们可以看看代码
1 2 3 4 5 6 7 8 9 10 11 local cookies = 10 repeat print ("饼干还剩:" .. cookies .. "个" ) cookies = cookies - 1 if cookies == 0 then print ("爱丽丝吃完了所有的饼干!" ) end until (cookies <= 0 )
我们修改一下条件语句
1 2 3 4 5 6 7 8 9 10 local cookies = 10 repeat cookies = cookies - 1 print ("饼干还剩:" .. cookies .. "个" ) if cookies == 0 then print ("爱丽丝吃完了所有的饼干!" ) end until (cookies <= 0 )
循环嵌套 哦,对了,和其他语言一样,循环是可以嵌套的,一些学过其他语言的小伙伴估计已经掌握了冒泡排序,插入排序这些了….吧?
这里就随便讲讲几种方式吧
1 2 3 4 5 for i = 1 , 3 do for j = 1 , 4 do print (string .format ("我是外层第%d次循环的第%d个" , i, j)) end end
1 2 3 4 5 6 7 8 9 10 11 local i = 1 while i <= 3 do local j = 1 while j <= 2 do print (string .format ("我是外层第%d次循环的第%d个" , i, j)) j = j + 1 end i = i + 1 end
1 2 3 4 5 6 7 for i = 1 , 3 do local j = 1 while j <= 2 do print ("这是第 " .. i .. " 行,第 " .. j .. " 列" ) j = j + 1 end end
当然还有repeat 的嵌套,不过这里不讲太多了,以后具体场景用到再说,包括那些排序算法什么的也是,现在学这些东西反正也用不上而且你们估计和我一样睡一觉起来大脑格式化了 狗头
break关键字 这个和其他语言里的break一模一样,break 用于立即终止当前循环 ,跳到循环后面的代码继续执行
1 2 3 4 5 6 7 for i = 1 , 10 do if i == 5 then break end print (i) end print ("循环结束" )
goto关键字 goto 是 Lua 5.2+ 引入的特性,可以跳转到指定的标签位置 ,但是因为太过于自由了,容易让代码变成牵一发动全身的屎山,所以最好不要用
语法格式为
1 2 3 ::label:: -- 定义标签(用双冒号包裹) goto label -- 跳转到标签位置
1 2 3 4 5 6 7 8 local a = 1 ::label:: print ("都给我玩终末地去,咕咕嘎嘎!" )a = a + 1 if a < 3 then goto label end
或者这种
我把这个标签放到程序的开头,这样可以使用goto重新触发,为防止无限循环,使用break跳出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 local round = 0 ::respawn:: local monkeyNumber = 10 local function killMonkey () monkeyNumber = monkeyNumber - 1 end for i = 1 , monkeyNumber do print ("还有" .. monkeyNumber .. "只猴子" ) killMonkey() if monkeyNumber == 0 then round = round + 1 print ("第 " .. round .. " 轮结束,猴子都死光了" ) if round == 3 then print ("游戏结束" ) break else goto respawn end end end
lua里面没有c语言里的那种continue,但是可以通过模拟来实现
我们都知道continue的作用是跳出当前的过程不执行,但是继续该过程以后的过程
比如
1 2 3 4 5 6 7 for i = 1 , 5 do if i == 3 then goto continue end print ("现在是" .. i) ::continue:: end
还有跳出多重循环
1 2 3 4 5 6 7 8 9 10 for i = 1 , 3 do for j = 1 , 3 do if i * j > 4 then goto exit end print ("第" .. i .. "行,第" .. j .. "列" ) end end ::exit :: print ("全部结束" )
if-else语句 这个和其他语言里的没啥区别,就是else if 变成了 elseif 写法
① 只写if 1 2 3 4 5 local money = 400 if money >= 300 then print ("速速购买黑神话吗喽" ) end
② if + else 1 2 3 4 5 6 7 local money = 100 if money >= 300 then print ("速速购买黑神话吗喽" ) else print ("没钱? 孩子,你还是去玩三角洲去吧" ) end
③ if + elseif + else 1 2 3 4 5 6 7 8 9 local money = 50 if money >= 300 then print ("速速购买黑神话吗喽" ) elseif money >= 200 then print ("孩子,玩只狼吧" ) else print ("没钱? 孩子,你还是去玩三角洲去吧" ) end
对了,lua里的if里的这个条件可以带括号也可以不带,一般不带,不过带了可读性更高
⚠️ 但是提醒一下,for循环不可以给条件语句带括号.否则会报错,但是其他循环可以
评论区