1. 程式人生 > >《lua程式設計》讀書筆記 第四章:語句

《lua程式設計》讀書筆記 第四章:語句

4.1 賦值

Lua支援“多重賦值”,即可以一次性將多個值賦予多個變數。

a,b = 10, 2*x

在多重賦值中,Lua先對等號右邊所有元素求值,然後才執行賦值,這樣便可以進行交叉賦值

x,y = y,x
a[i], a[j] = a[j], a[i]

Lua總是會將等號右邊值的個數調整到與左邊變數數量相等。規則是:若值的個數少於變數個數,則多餘的變數被賦予nil;若值的個數多於變數個數,則舍多餘的值。

a,b,c = 0, 1        -->c為nil
a,b = 0, 1, 2       -->值2被捨棄

注意要初始化一組變數,應為每個變數都提供一個值

a,b,c = 0       -->只有a被賦值
a,b,c = 0, 0, 0

多重賦值語句並不比等價的多條賦值語句更快。其一般比較多用於交換兩個變數的值,以及收集函式的多個返回值。

4.2 區域性變數與塊

通過local語句來建立區域性變數。與全域性變數不同的是,區域性變數的作用域僅限於宣告它的那個塊。一個塊是一個控制結構的執行體、或者是一個函式的控制體,再或者是一個程式塊。另外,區域性變數會遮蔽相同名稱的全域性變數。

x=10
local i = 1
while i <= x do
    local x = i * 2
    print(x)                 -->區域性變數x
i = i + 1 end print(x) -->全域性變數x

儘可能的使用區域性變數是一種良好的程式設計習慣,區域性變數可以避免汙染全域性作用域,此外,訪問區域性變數比訪問全域性變數更快,最後,一個區域性變數通常會隨著其作用域的結束而消失,這樣便使垃圾收集器可以及時釋放其值。
在Lua中,有一種習慣的寫法:

local foo = foo   -->用全域性變數foo來初始化區域性變數foo

這種寫法可以加速在當前作用域中對foo的訪問。

4.3 控制結構

4.3.1 if then else

若要編寫巢狀的if,則用elseif
結構:

if cond then ... end
if cond then ... else ... end
if cond then ... elseif ... then ... else ... end

4.3.2 while

結構:

while cond
    ...
end

4.3.3 repeat

結構:

repeat
    ...
until cond

4.3.4 數字型for

結構:

for var = exp1,exp2,exp3 do
    ...
end

var從exp2變化到exp2,每次變化步長遞增exp3,exp3若不指定,則預設為1, 如果不想給迴圈設定上限,則可以使用math.huge:

for i = 1, math.huge do
    ...
end

另外還需要注意一些細節,首先,for的三個表示式是在迴圈開始前一次性求值的,其次,控制變數會自動宣告為for語句的區域性變數,並且只在迴圈體內部可見,因此,控制變數在迴圈結束後就不存在了。最後一點,不要在迴圈過程中改變控制變數的值,否則將導致不可預知的結果。

4.3.5 泛型for

泛型for通過迭代器來遍歷所有值。泛型for通過不同的迭代器,幾乎可以遍歷所有東西,並且寫出的程式碼極具可讀性。標準庫提供了幾種迭代器,包括io.lines,pairs,ipairs,string.gmatch等。
泛型for和數字型for有兩個2共同點:1.迴圈變數是迴圈體的區域性變數;2.絕不應該對迴圈變數做任何賦值。

4.4 break與return

break語句用於結束一個內部迴圈,而不會影響外層的迴圈,return則用於結束一個函式的執行。
由於語法構造的原因,break或return只能是一個塊的最後一條語句。換句話說, 它們是程式塊的最後一條語句,或者是end、else、until前的最後一條語句
有時我們希望那些位於return後面的語句無法執行(比如除錯時),那麼可以通過手動新增do end來實現:

function foo()
    do return end
    ...
end