1. 程式人生 > 其它 >lua基本語法之分支結構二

lua基本語法之分支結構二

之前我們介紹了
條件判斷的 if
用於迴圈迭代的 while、repeat

四)for 控制結構

for 語句有兩種形式:數字 for範型 for

1)數字型 for 的語法如下:

for var = begin, finish, step do
    --body
end

關於數字 for 需要關注以下幾點:

1.var 從 begin 變化到 finish,每次變化都以 step 作為步長遞增 var

2.begin、finish、step 三個表示式只會在迴圈開始時執行一次

3.第三個表示式 step 是可選的,預設為 1

4.控制變數 var 的作用域僅在 for 迴圈內,需要在外面控制,則需將值賦給一個新的變數 5.迴圈過程中不要改變控制變數的值,那樣會帶來不可預知的影響

for i = 1, 5 do
  print(i)
end

-- output:
1
2
3
4
5

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

-- output:
1
3
5
7
9


for i = 10, 1, -1 do
  print(i)
end

-- output:
10
9
8
7
6
5
4
3
2
1

如果不想給迴圈設定上限的話,可以使用常量 math.huge:

for i = 1, math.huge do
    if (0.3*i^3 - 20*i^2 - 500 >=0) then
      print(i)
      break
    end
end

2)for 泛型

對lua的table型別進行遍歷

泛型 for 迴圈通過一個迭代器(iterator)函式來遍歷所有值:
-- 列印陣列a的所有值

local a = {"a", "b", "c", "d"}
for i, v in ipairs(a) do
  print("index:", i, " value:", v)
end

-- output:
index:  1  value: a
index:  2  value: b
index:  3  value: c
index:  4  value: d

Lua 的基礎庫提供了 ipairs,這是一個用於遍歷陣列的迭代器函式。在每次迴圈中,i 會被賦予一個索引值,同時 v 被賦予一個對應於該索引的陣列元素值。

下面是另一個類似的示例,演示瞭如何遍歷一個 table 中所有的 key

-- 列印table t中所有的key
for k in pairs(t) do
    print(k)
end

pairs可以把陣列型別和雜湊型別索引值,都會迭代出來

=========================================================

對於泛型 for 的使用,再來看一個更具體的示例。假設有這樣一個 table,它的內容是一週中每天的名稱:

local days = {
  "Sunday", "Monday", "Tuesday", "Wednesday",
  "Thursday", "Friday", "Saturday"
}

k v ===》 v  ,k

現在要將一個名稱轉換成它在一週中的位置。為此,需要根據給定的名稱來搜尋這個 table。然而 在 Lua 中,通常更有效的方法是建立一個“逆向 table”。例如這個逆向 table 叫 revDays,它以 一週中每天的名稱作為索引,位置數字作為值:
local revDays = {
["Sunday"] = 1,
["Monday"] = 2,
["Tuesday"] = 3,
["Wednesday"] = 4,
["Thursday"] = 5,
["Friday"] = 6,
["Saturday"] = 7
}

接下來,要找出一個名稱所對應的需要,只需用名字來索引這個 reverse table 即可:
local x = "Tuesday"
print(revDays[x]) -->3

當然,不必手動宣告這個逆向 table,而是通過原來的 table 自動地構造出這個逆向 table:



local days = {
   "Monday", "Tuesday", "Wednesday", "Thursday",
   "Friday", "Saturday","Sunday"
}

local revDays = {}
for k, v in pairs(days) do
  revDays[v] = k
end

-- print value
for k,v in pairs(revDays) do
  print("k:", k, " v:", v)
end

-- output:
k:  Tuesday   v: 2
k:  Monday    v: 1
k:  Sunday    v: 7
k:  Thursday  v: 4
k:  Friday    v: 5
k:  Wednesday v: 3
k:  Saturday  v: 6

這個迴圈會為每個元素進行賦值,其中變數 k 為 key(1、2、...),變數 v 為 value("Sunday"、"Monday"、...)。
值得一提的是,在 LuaJIT 2.1 中,ipairs() 內建函式是可以被 JIT 編譯的,而 pairs() 則只能被解釋執行。因此在效能敏感的場景,應當合理安排資料結構,避免對雜湊表進行遍歷。事實上,即使未來 pairs 可以被 JIT 編譯,雜湊表的遍歷本身也不會有陣列遍歷那麼高效,畢竟雜湊表就不是為遍歷而設計的資料結構。

五)break,return 關鍵字

1)break
語句 break 用來終止 while、repeat 和 for 三種迴圈的執行,並跳出當前迴圈體, 繼續執行當前迴圈之後的語句。下面舉一個 while 迴圈中的 break 的例子來說明:
-- 計算最小的x,使從1到x的所有數相加和大於100
sum = 0
i = 1
while true do
sum = sum + i
if sum > 100 then
break
end
i = i + 1
end
print("The result is " .. i) -->output:The result is 14
在實際應用中,break 經常用於巢狀迴圈中。

2)return
return 主要用於從函式中返回結果,或者用於簡單的結束一個函式的執行。
return 只能寫在語句塊的最後,一旦執行了 return語句,該語句之後的所有語句都不會再執行。

執行return方法,如果實在主函式體裡面,不在語句塊中;執行return 且沒有返回值,之後的語句照樣會執行

若要寫在函式中間,則只能寫在一個顯式的語句塊內,參見示例程式碼:

local function add(x, y)
    return x + y
end

local function is_positive(x)
    if x > 0 then
        return x .. " is > 0"
    else
        return x .. " is not > 0"
    end

    print("function end!")
end

--由於return只出現在前面顯式的語句塊,所以此語句不註釋也不會報錯
--,但是不會被執行,此處不會產生輸出

sum = add(10, 20)
print("The sum is " .. sum)  -->output:The sum is 30
answer = is_positive(-10)
print(answer)                -->output:-10 is is not > 0

有時候,為了除錯方便,我們可以想在某個函式的中間提前 return,以進行控制流的短路。此時我們可以將 return 放在一個 do ... end 程式碼塊中,例如:

local function add(x, y)
    print(1)
    return
    print(2)
end
--return 不放在語句塊中,return 也沒有返回值,不註釋該語句,不會報錯; 但會執行return之後的業務

local function add(x, y)
    print(1)
    do return end
    print(2)
end