---
# System prepended metadata

title: 【Lua 筆記】迴圈 - part 4
tags: [Lua, 程式語言]

---

【Lua 筆記】迴圈 - part 4
===

目錄（Table of Contents）：

[TOC]

---

由於有款遊戲叫做 CSO（Counter-Strike Online），內建模式創世者模式（Studio）新增使用 Lua 及其遊戲的 API，所以突發奇想製作這個筆記。

這個筆記會在一開始先著重純粹的程式設計自學，在最後的章節才會與 CSO 遊戲 API 進行應用。

迴圈（loop）
---

迴圈即一個循環。

很多時候我們會需要重複執行一個動作，以生活舉例，像是平時上廁所（無論小便、大便）會是一個迴圈，因為這是我們不斷持續在做的事情。又或者是在長跑時，跑了好幾圈操場，這也是一種迴圈。

回到正題，Lua 共支援以下幾種迴圈語法：

* while
* for
* repeat...until
* break
* goto

while、for 一定是每個程式語言基本配備，接下來讓我們先來看看 while 迴圈：

### while 迴圈
---

while 是一種具有條件判斷的迴圈，格式如下：

```lua=
while (condition) do
   statements
end
```

當 condition 這個條件成立，也就是 condition = true 的時候，迴圈才會執行。

至於執行什麼內容呢？執行 statements 裡面的內容。如果裡面都沒有設定可以讓條件變成 false 的機制，則會形成一個無窮迴圈，就會一直循環下去。

condition 可以是任意的運算式。

```lua=
a = 10
while (a < 20) do
   print("The value of a is:", a)
   a = a + 1
end
```

輸出結果：

```
The value of a is:  10
The value of a is:  11
The value of a is:  12
The value of a is:  13
The value of a is:  14
The value of a is:  15
The value of a is:  16
The value of a is:  17
The value of a is:  18
The value of a is:  19
```

可以看到上面的程式碼當中，當 a < 20 它才會執行 while 裡面的內容，然後裡面有設定不斷累加的機制，使條件變成 false 後才能離開迴圈。

### 無限迴圈
---

無限迴圈即意味著一個迴圈指令判斷永遠都是 true。

```lua=
while (true) do
    print("Hi")
end
```

輸出結果：

```
Hi
Hi
Hi
HI
....
```

備註：按下 ctrl + C 在終端上表示中斷執行結果。

### for 迴圈
---

for 迴圈的機制宛如等差數列，而以下是它的格式：

```lua=
for var=exp1,exp2,exp3 do  
    statements
end  
```

這有點像 C 語言的寫法：

```c=
for (i; i < 10; i++){
    statements
}
```

不過如果沒學過 C 語言的話，可以不用鳥這個東西。

exp1，是作為 var 的初始值，這邊要注意的是 var 是個變數，你想怎麼叫它都行，不過通常我們會用 i 來表示。

i 即 iteration，表示迭代，也就是重複的意思。

exp2，表示從 exp1 這個數值開始，要重複到 exp2 這個數值。

exp3，表示在當 exp1 重複到 exp2 的過程中，每次增加的數值，預設為 1，也可以不加 exp3。

看了這個解釋，如果你還是霧煞煞的話，我們來看個範例：

```lua=
for i=1,10 do
  print(i)
end
```

輸出結果：

```
1
2
3
4
5
6
7
8
9
10
```

for 就是個等差數列，上面程式碼的意思就是從 1，遞增 1 直到 10 結束。

使用 while 迴圈可以這樣表達：

```lua=
i = 1
while (i <= 10) do
  print(i)
  i = i + 1
end
```

接下來我們來做個範例，從 2x1 ~ 2x10 的程式碼：

```lua=
for i = 1, 10 do
  i = i * 2
  print(i)
end
```

輸出結果：

```
2
4
6
8
10
12
14
16
18
20
```

### repeat...until
---

> for 和 while 迴圈的條件語句在目前迴圈執行開始時判斷，而 repeat...until 迴圈的條件語句在目前迴圈結束後判斷。

語法格式：

```lua=
repeat
   statements
until( condition )
```

什麼意思？來看例子就知道（[Lua repeat…until 循环 | 菜鸟教程](https://www.runoob.com/lua/lua-repeat-until-loop.html)）：

```lua=
a = 10
repeat
   print("a is :", a)
   a = a + 1
until( a > 15 )
```

輸出結果：

```
a is : 10
a is : 11
a is : 12
a is : 13
a is : 14
a is : 15
```

欸？如果我們改用 while 迴圈寫的話會怎樣？我們一樣來試試看：

```lua=
a = 10
while (a < 15) do
    print("a is :", a)
    a = a + 1
end
```

輸出結果：

```
a is :  10
a is :  11
a is :  12
a is :  13
a is :  14
```

其實 Lua 語言的設計都很直觀，像是 repeat ... until，「重複直到」。以上面例子就是，a 不斷 + 1 直到 a > 15。

而前面所述 for、while 迴圈的判斷都在迴圈執行時就馬上判斷了，也可以從上面例子看出來。

程式語言連結：repeat ... until 其實像是 C 的 do ... while。

### break 語句
---

break 語句相當於打斷的意思，打斷什麼呢？打斷一個迴圈，所以它的功用就是能夠在迴圈途中打斷執行。

我們來做個範例：

```lua=
for i=1,10 do
  print(i)
  if i == 5 then
    break
  end
end
```

輸出結果：

```
1
2
3
4
5
```

可以發現原本迴圈要遞增至 10 才會結束，而使用判斷式判斷如果 i == 5，執行 break 語句，使整體迴圈馬上結束，接著繼續執行後續的程式碼。

### goto 語句
---

goto 語句是筆者認為 Lua 當中數一數二特別的語法，因為它能將控制流程無條件地轉到被標記的語句處。

什麼意思呢？待會解釋。

首先它的語法格式長這樣：

```lua=
goto Label
```

Label 的格式：

```lua=
:: Label ::
```

這個標籤後面可以放上要執行的程式碼，像是下面這個例子：

```lua=
::Label:: print("Hello")
goto Label
```

輸出結果：

```
Hello
```

再來做這個例子（[Lua goto 语句 | 菜鸟教程](https://www.runoob.com/lua/lua-goto.html)）：

```lua=
a = 1
::label:: print("--- goto label ---")

a = a + 1
if a < 3 then
    goto label
end
```

輸出結果：

```
--- goto label ---
--- goto label ---
```

為什麼會輸出兩次？這是你我都會疑惑的問題，別忘了 goto 被執行時會「跳轉」到標籤的語句處，也就是程式碼將會在 `::label:: print("--- goto label ---")` 這邊開始重複執行，這就是 goto 神奇的地方了。

最後，我們做完這個例子就放學了（[Lua goto 语句 | 菜鸟教程](https://www.runoob.com/lua/lua-goto.html)）：

```lua=
for i=1, 3 do
    if i <= 2 then
        print(i, "yes continue")
        goto continue
    end
    print(i, " no continue")
    ::continue::
    print([[i'm end]])
end
```

輸出結果：

```
1   yes continue
i'm end
2   yes continue
i'm end
3    no continue
i'm end
```

因為 lua 當中沒有 continue 這個語句，但是我們可以透過 goto 來還原，同樣能達到 continue 的效果，只是稍嫌麻煩而已。

備註：[[i'm end]] 的原來寫法格式為 [[...]]，為什麼要這樣寫？因為原本寫 print("i'm end") 是會發生錯誤的，因為一個字串裡面只能有兩個成對的單雙引號，而用這個兩個中括號的格式寫，就能夠容許有引號或任何字元的出現。

字元："一個"中文字、符號、英文字母等等都稱為字元。

字串：一串字元的結合體。

另外，標籤不一定只能夠設定單一條程式碼而已，如下範例（[Lua goto 语句 | 菜鸟教程](https://www.runoob.com/lua/lua-goto.html)）：

```lua=
i = 0
::s1:: do
  print(i)
  i = i+1
end
if i>3 then
  os.exit()
end
goto s1
```

輸出結果：

```
0
1
2
3
```

總結
---

迴圈就是一個循環，一個 circle。

Lua 共支援以下幾種迴圈語法：

* while
* for
* repeat...until
* break
* goto

while 是一個有條件判斷的迴圈：

```lua=
while (condition) do
   statements
end
```

無限迴圈即意味著一個迴圈指令判斷永遠都是 true。

```lua=
while (true) do
    print("Hi")
end
```

for 迴圈的格式：

```lua=
for var=exp1,exp2,exp3 do  
    statements
end  
```

exp1 -> 初始值
exp2 -> 到哪個值停下
exp3 -> 等差數列的公差

repeat ... until 語法格式：

```lua=
repeat
   statements
until( condition )
```

break -> 用於中斷迴圈執行的指令。

goto -> 能夠透過自定義的標籤，並且移轉到該標籤的地方，從此開始執行。

最後小提醒，雖然本篇沒有講到巢狀迴圈，但其實概念都是相同的，在這邊就不再贅述，備註：***巢狀迴圈比巢狀條件判斷還重要哦。***

參考資料
---

[【30天Lua重拾筆記15】基礎2: Label and Goto - iT 邦幫忙::一起幫忙解決難題，拯救 IT 人的一天](https://ithelp.ithome.com.tw/articles/10245675)

[Day7 開機學習 Lua - 條件判斷與迴圈控制 - iT 邦幫忙::一起幫忙解決難題，拯救 IT 人的一天](https://ithelp.ithome.com.tw/articles/10264262)

[【30天Lua重拾筆記13】基礎2: 控制-for迴圈 - iT 邦幫忙::一起幫忙解決難題，拯救 IT 人的一天](https://ithelp.ithome.com.tw/articles/10244489)

[Lua 循环 | 菜鸟教程](https://www.runoob.com/lua/lua-loops.html)

[Lua while 循环 | 菜鸟教程](https://www.runoob.com/lua/lua-while-loop.html)

[Lua for 循环 | 菜鸟教程](https://www.runoob.com/lua/lua-for-loop.html)

[Lua repeat…until 循环 | 菜鸟教程](https://www.runoob.com/lua/lua-repeat-until-loop.html)

[Lua break 语句 | 菜鸟教程](https://www.runoob.com/lua/lua-break-statement.html)

[Lua goto 语句 | 菜鸟教程](https://www.runoob.com/lua/lua-goto.html)