lua學習之複習彙總篇

第六日筆記

1. 基礎概念

程序塊

定義

  1. 在 lua 中任何一個源代碼文件或在交互模式中輸入的一行代碼
  2. 程序塊能夠是任意大小的
  3. 程序塊能夠是一連串語句或一條命令
  4. 也可由函數定義構成,通常將函數定義寫在文件中,而後用解釋器執行這個文件
  5. 換行在代碼中不起任何做用,只是爲了提高可讀性
  6. 分隔符 ; 起分隔做用
a = a * 2 
b = a * b

a = a * 2;
b = a * b

a = a * b; b = a * b
a = a * b b = a * b

交互模式

在交互模式中輸入的一行內容會被解釋器看成一個完整的程序塊,若是這一行的內容不足以構成一個完整的程序塊,就會等待輸入html

退出交互模式
  1. Ctrl + Z 是 end-of-file 控制字符,在 dos 中是這個快捷鍵
  2. os.exit() 標準庫中的退出函數

區域設置

  1. lua 中識別什麼是字母是經過區域設置來判別的
  2. 如設置希臘,就能夠識別希臘字母做爲變量
  3. 但在不支持該區域的系統上沒法執行

執行函數文件

  1. lua 函數文件路徑
  2. dofile("文件路徑 / 須要轉義") 加載函數庫
-- 階乘函數
function fact(n) 
    if n == 0    then
        return 1 --0 的階乘是 1
    else
        return n * fact(n - 1) -- 3 的階乘, 3 * 2 * 1
    end
end
print("Enter a number:")
a = io.read("*number")  -- 讀取用戶輸入且需爲數字類型的
print(fact(a)) --調用階乘函數,並傳入實參 a 

-- lib1 函數庫
function norm(x, y)
    return (x ^ 2 + y ^ 2) ^ 0.5  -- 兩個數的平方和再開平方根
end
function twice(x)
    return 2 * x -- 一個數的兩倍
end

標識符

定義

  1. 由任意數字、字母、下劃線構成的字符串叫作標識符
  2. 標識符不能由數字開頭
  3. 標識符不能如下劃線開頭後跟多個大寫字母
  4. 如: _PROMPT, _VERSION
  5. lua 將它們保留用做特殊用途,被稱爲啞變量
_PROMPT = ">lua"  -- 修改交互模式中的提示符,默認爲 >

保留字

流程控制
  1. if
  2. then
  3. elseif
  4. end
  5. for
  6. do
  7. in
  8. while
  9. repeat
  10. until
if 條件表達式 then
    elseif 條件表達式 then
end
for 控制變量, 終止變量, 步長 do
     <循環體>
end
a = {}
for i,v in ipairs(a) do
    <循環體>
end
while i < 10 do
    i = i + 1
    print(i)
end
repeat
    i = 0
    i = i + 1
until i > 10
條件控制
  1. true
  2. false
邏輯控制
  1. and
  2. or
  3. not
類型
  1. function
  2. local
  3. nil
須要注意的點
  1. nil == nil 是相等的
  2. and And 不一樣,lua 區分大小寫
  3. lua 中條件值不只僅只有 truefalse
  4. 在 lua 中任何值除了 falsenil 均可以用做表示「真」
  5. 包括空字符串 "" 和數字 0

註釋

  1. 單行註釋 --
  2. 多行註釋 --[[]]
  3. 使多行註釋中的代碼生效 ---[[ <代碼塊> --]]
  4. 多行註釋中包含多行註釋 --[==[ <多行註釋> ]==]

全局變量

  1. 全局變量不須要聲明,只須要將一個值賦給它便可
  2. lua 中能夠訪問一個未初始化的變量且不會發生錯誤
  3. 但這個未初始化的變量的值爲 nil
  4. 刪除全局變量賦值 nil 便可
  5. lua 將全局變量存儲在一個普通的 table 中

解釋器

參數

  1. -i 先執行程序塊,後進入交互模式
  2. -e 直接執行代碼塊
  3. -l 加載庫文件

解釋器執行參數前

  1. 會先尋找一個叫作 LUA_INIT 的環境變量
  2. 找到了,且內容爲 @文件名 的話,就執行這個文件
  3. 沒找到,就假設內容爲 lua 代碼, 並執行

解釋器運行腳本前

  1. lua 將腳本前的參數存儲到 arg 這個 table 中,用做啓動參數
  2. 腳本名在這個 table 中的索引爲 0,其後參數依此類推
  3. 腳本名前的參數爲負數索引
lua -i -e "hello" script a b 
arg[0] = "script"
arg[1] = "a"
arg[-1] = "hello"
arg[-2] = "-e"
arg[-3] = "-i"
  1. 在 lua 中也能夠經過變長參數語法來檢索腳本參數
  2. 變長參數爲 ... 三個點,做爲函數參數傳遞時表示傳遞全部參數

2. 類型與值

  1. lua 是動態類型語言
  2. 每一個值都攜帶有它的類型信息

獲取值的類型

  1. type() 能夠返回一個值的類型名稱
  2. type()的返回結果永遠是 string 類型的
print(type(3)) -- number
print(type("a")) -- string
print(type({"a", "b", "c"})) -- table
print(type(io.read)) -- function
print(type(true)) -- boolean

number

  1. 實數,即雙精度浮點數
  2. 可以使用科學計數法,如 2e2 表示 200
  3. 可從新編譯 lua,使用其餘類型的值來表示數字類型,如 long
  4. tonumber() 用於將一個字符串顯式的轉換爲數字類型

boolean

  1. 在 lua 中,有兩個布爾值一個是 true 表示爲「真」,一個是 false 表示爲「假」
  2. 但,這兩個值不是用來表示條件的惟一值,在 lua 中 除 nilfalse 外的任何值,均可以用來表示

    「真」, 包括空字符串 "" 和數字 0數組

nil

  1. 只有一個值,nil
  2. 僅用來表示爲空,表示未初始化的變量或 table 元素
  3. 也可用來刪除變量或 table 元素

string

  1. 是對象,由自動內存回收器進行分配和釋放
  2. 是字符序列,是8位編碼
  3. 能夠包含數值編碼,如二進制
  4. lua 中的字符串是惟一不可變的值
  5. .. 字符串鏈接符,用於鏈接兩個字符串,但數字類型使用時須要用空格隔開
  6. # 長度操做符,後跟字符串,能夠獲取字符串長度
  7. [[]] 在期內的特殊字符不須要轉義
  8. [==[ <多行註釋> ]==] 能夠正確打印多行註釋的內容
  9. "3" + 4 這樣的值會是 number 類型,發生了運行時隱式轉換
print("\97" == "a") -- 在 ASCII 編碼表中,\97 表示爲 a
print(type(3 .. "")) -- string
print(3..4) --報錯
print(3 .. 4) -- 34
print(#"hello") -- 5

-- 獲取子串,證實字符串是不可變的值
a = "hello"
b = a .. " ,world"
print(a) -- hello
print(b) -- hello, world
a = [[
    <html>
        <head><title>蕪湖</title></head>
        <body></body>
    </html>
]]
a = [==[
    --[[
        print("多行註釋")
        print("多行註釋")
    ]]
]==]
print(type("3" + 4)) -- number

顯式轉換爲字符串

  1. tostring()
  2. .. "" 任意數字鏈接一個空字符串便可轉換爲字符串

table

  1. 是對象,由自動內存回收器進行分配和釋放
  2. table 沒有固定大小,能夠動態添加元素
  3. {} 是 table 構造式,用來建立一個 table
  4. # 長度操做符能夠獲取 table 的大小
  5. table 中的元素在未被初始化前都是 nil
  6. 能夠將 table 中的元素賦值 nil 來進行刪除
  7. 若是 table 中間部分的元素值爲 nil 就說明這是一個有「空隙」的 table
  8. 有「空隙」的 table 要使用 table.maxn() 來返回這個函數的最大正索引數
  9. table 能夠用來表示模塊、包、對象
  10. table 中的索引能夠是任何值,除了 nil
  11. table 是匿名的
  12. 程序僅保留了對 table 的一個引用
  13. 一個僅有 table 的變量和 table 自身並無關係
  14. a.x 等價於 a["x"]以字符串爲索引的
  15. a[x] 是以變量 x 爲索引的
a = {}
for i = 1, 10 do
    a[i] = i
    print(a[i])
end
for i = 1, #a do
    print(a[i])
end
print(a[10]) -- 10
print(#a) -- 10
a[10] = nil
print(#a) -- 9
a[10000] = 666
print(#a) -- 9
print(table.maxn(a)) -- 10000
a = {}
b = {}
c = a 
print(type(a == b)) -- false
print(type(a == c)) -- true
x = "y"
a["x"] = 666
a["y"] = 777
print(a.x) --666
print(a[x]) -- 777

function

  1. 第一類值
  2. 能夠存儲在變量中
  3. 能夠做爲函數的返回值或參數
  4. lua 能夠調用自身編寫的函數也能夠調用 C 語言編寫的函數
  5. lua 標準庫中的函數都是用 C 語言編寫的

userdata

  1. 由應用程序或 C 語言編寫建立的新類型
  2. 沒有太多的預約義操做
  3. 僅用來作賦值和條件測試

3. 表達式

定義

  1. 表達式用於表示值
  2. 在 lua 中,函數調用,函數定義,數字常量、字面字符串,變量,一元和二元操做符,table 構造式都是表達式

算數操做符

一元操做符

  1. - 負號

二元操做符

  1. +
  2. - 減號
  3. *
  4. /
  5. %
  6. ^
-- % 的技巧
-- x % 1
print(3.13 % 1) -- 獲得小數部分
-- x - x % 1
print(3.14 - 3.14 % 1) -- 獲得整數部分
-- x - x % 0.1
print(3.14 - 3.14 % 0.1) -- 獲得整數部分 + 一位小數部分
-- x - x % 0.01 以此類推,是整數部分 + 兩位小數部分

關係操做符

  1. >
  2. <
  3. >=
  4. <=
  5. == 相等性判斷
  6. ~= 不等性判斷

邏輯操做符

  1. and 第一個操做數爲假,返回第一個,不然返回第二個
  2. or 第一個操做數爲真,返回第一個,不然返回第二個
  3. not 只會返回 truefalse
-- 短路操做的使用技巧
print(x = x or v) -- 初始化一個值,若是 x 爲 nil 沒有被初始化過,就賦值 v 
-- 等價於
if not x then 
    x = v
end
-- 實現 C 語言中的三元操做符, a ? b : c
print((a and b) or c) -- b 必須爲真,才能夠這樣操做
-- 等價於
if a == true then
    return b
elseif a == false then
    return c
end
-- 實現返回兩個數中的較大值
max = (x > y) and x or y -- 由於 lua 將數字視爲「真」
-- 等價於
if x > y then
    return x
else
    return y
end

字符串鏈接

  1. .. 字符串鏈接

優先級

1級優先

  1. ^

2級優先

  1. - 負號
  2. not
  3. #

3級優先

  1. *
  2. /
  3. %

4級優先

  1. +
  2. - 減號

5級優先

  1. .. 字符串鏈接

6級優先

  1. >
  2. <
  3. >=
  4. <=
  5. ==
  6. ~=

7級優先

  1. and

8級優先

  1. or

table 構造式

  1. lua 標準庫中的函數對 table 的索引都是從 1 開始處理的

記錄風格的 table

a = {x = 10, y = 20} -- 等價於 a.x = 10, a.y = 20

混合使用的 table

  1. 這種方式的 table 不能以負數和操做符做爲索引
a = {
    color = {"red", "green", "blue"}
    width = 200,
    height = 300
}

鏈表

  1. 由一系列節點組成,節點就是元素
  2. 節點能夠再運行時動態生成
  3. 每一個節點包括兩部分函數

    1. 存儲數據的數據域
    2. 存儲下一個地址節點的指針域
list = nil
for line in io.lines() do
    list = {next = list, value = line}
end
local l = list
while l do
    print(l.value)
    l = l.next
end

指定索引的 table

options = {["+"] = "add", ["-"] = "sub", 
    ["*"] = "mul", ["/"] = "div"}
print(options["+"]) -- "add"

4. 語句

  1. 在 lua 中包括賦值,程序結構和過程調用
  2. 還有多重賦值和局部變量聲明

賦值

  1. lua 支持多重賦值,即 a, b = 1, 2
  2. 會先計算等號右邊全部元素的值,而後再賦值
  3. 若是右邊的值少於左邊變量,未被初始化的變量就置爲 nil
  4. 若是左邊變量少於右邊的值,多餘的值會被「拋棄」
  5. 可用來收集函數的多個返回值
  6. 初始化變量就是爲每個變量賦一個初始值
a, b = 1, 2
x, y  = y, x -- 交換變量
a, b = 1 -- a = 1, b = nil
a, b = 1, 2, 3 -- a = 1, b = 2, 3 被拋棄
a, b = f() -- a 接收函數 f 的第一個返回值,b 接收第二個
a, b, c = 0, 0, 0 -- 初始化賦值

局部變量與塊

  1. 一個塊就是程序結構的執行體,或函數的執行體
  2. 在塊內聲明的變量僅在塊內生效,即做用域爲聲明它們的塊
  3. 可顯式聲明一個塊使用 do <要執行的內容> end 將要執行的內容包裹在一個塊內

局部變量

  1. local 用來聲明一個局部變量
  2. 局部變量僅在聲明它的塊內生效,在塊的外部無效
  3. 如:在循環內部聲明在的變量在循環外部則沒法使用
a = 3
b = 0
if a then
    local a = 5
    b = a -- 將 then 塊內的局部變量 a ,保存到全局變量 b 中
    print(a)
end
print(a) -- 3
print(b) -- 5
do
    -- code block
end

儘可能使用局部變量

  1. 使用局部變量要比全局變量要快
  2. 避免污染全局環境
  3. 局部變量僅在聲明它的塊中有效,即在塊外這個變量就被釋放掉了
  4. lua 將局部變量聲明看成語句處理,便可以在任何支持書寫語句的地方書寫局部變量聲明
  5. 聲明能夠包含初始化賦值

程序結構

  1. 程序結構中的條件表達式能夠是任何值

條件結構

  1. if
  2. elseif
  3. else
if 條件表達式 then 
     <執行體> -- 符合條件表達式執行
end
if 條件表達式1 then
    <執行體 1> -- 符合條件表達式 1 執行
    elseif 條件表達式2 then
    <執行體 2> -- 符合條件表達式 2 執行
end
if 條件表達式 then
    <執行體 1>  -- 條件表達式爲真時執行
else
    <執行體 2>  -- 條件表達式爲假是執行
end

循環結構

  1. for
  2. while 條件表達式爲時退出
  3. repeat ... until 條件表達式爲時推出,條件測試是在循環體以後作的,所以循環體至少會執行一次
  4. 在循環體內聲明的局部變量的做用域包含了條件測試
  5. 循環的三個表達式是在循環開始前一次性求值的
  6. 控制變量會被自動聲明爲 for 塊中的局部變量,即做用域爲 for 塊,在循環結束後不可見
  7. 不要在循環過程當中修改控制變量的值
  8. 可使用 breakreturn 在循環正常結束前提早結束它
for exp1, exp2, exp3 do
   <循環體> 
end
while 條件表達式 do
    <循環體>
end
repeat 
    <循環體>
until 條件表達式
a = 20
repeat
    local a = 0
    print(a)
until a == 0 -- 可訪問在 repeat 塊內聲明的 a, 而不是全局變量 a
數值型 for
for i = 10, 0, -1 do
    print(i)
end
泛型 for
  1. ipairs() 用來遍歷數組
  2. i 每次循環時都會賦予一個新的索引值,v 則是索引值所對應的元素
a = {1, 2, 3, 4, 5, 6}
for i,v in ipairs(a) do 
    print(i)
    print(v)
end
for i,v in pairs(a) do
    print(i)
    print(v)
end
兩種 for 的共同點
  1. 循環變量都是循環體的局部變量
  2. 不該該對循環遍歷進行賦值
days = {"第一天", "次日", "第三天"}
revdays = {}
for i, v in ipairs(days) do
    revdays[v] = i -- 逆向數組,將數組索引和數組元素調換,可獲取數組元素的位置
end
print(revdays["次日"]) -- 獲取次日所在位置

break 和 return

  1. break 用於結束一個循環,跳出內層循環後在外層循環中繼續執行
  2. return 用於返回函數結果或簡單的結束函數的執行
  3. 任何函數的結尾處實際都有一句隱式的 return
  4. 若是函數無返回值,就無需在結尾處加 return

二者的共同點

  1. 都是用做跳出當前塊
  2. 都須要放在一個塊的結尾處,即一個塊的最後一條語句
  3. 由於 returnbreak 後的語句將沒法執行到
  4. 能夠用 do ... end 塊包裹 return,用與調試,即調用函數但不執行函數內容的狀況
a = 1
if a then
   print("hello")
   break
   print("world") -- 會報錯
end
for i = 1, 10 do
    print(i)
    if i > 3 then
        break -- 只會打印 1 2 3 4 而後就跳出循環了
    end
end
-- 調試
function foo(...)
    do
           return 
    end
    print("執行 foo 函數") -- 不會打印
end
foo(1, 2 ,3)

5. 函數

  1. 函數是對語句和表達式進行抽象的主要機制

函數的兩種用法

  1. 一是能夠完成特定的任務,一句函數調用被視爲一條語句
  2. 二是隻用來計算並返回特定結果,視爲一句表達式
print("hello") -- 用來完成打印任務,視爲一條語句
a = os.date() -- os.date() 用來返回日期,視爲一句表達式

兩種用法的共同點

  1. 都須要將全部參數放到一對圓括號中 ()
  2. 但當參數爲字面字符串或 table 構造式的時候 ()能夠省略
  3. 即便調用函數沒有參數,也必需要有一對空的圓括號 ()
print "hello" -- hello
print {1, 2, 3} -- 1 2 3
print(os.date) -- 當前日期

定義

  1. function 是建立函數的關鍵字
  2. function add add 是函數的名稱
  3. function add(n) n 是函數的形式參數,簡稱爲形參
  4. add(4) 4 是調用 add()函數時的實際參 ,簡稱爲實參
  5. 實參多餘形參,多餘的實參被「拋棄」
  6. 形參多餘實參,多餘的形參被置爲nil
function foo(a, b)
    return a or b
end
foo(1) -- a = 1, b = nil
foo(1, 2) -- a = 1, b = 2
foo(1, 2, 31) -- a = 1, b = 2, 多餘的 31 被拋棄
-- 面向對象式調用
o.foo(o, x)
o:foo(x) -- 與上面的效果同樣,: 冒號操做符,隱式的將 o 做爲第一個參數

多重返回值

  1. lua 中的函數容許返回多個結果
  2. 用逗號分隔所須要返回的全部參數
string.find("you are cool", "are") -- 5 7 返回找到的字符串的開頭位置和結尾位置
-- 查找數組中的最大元素,並返回這個元素的所在位置
function maximum(a)
    local val = 1
    local max = a[val]
    for i,v in ipairs(a) do
        if max < a[i] then
            max = a[i]
            val = i
        end
    end
    return max, val
end
a = {1, 2, 55, 22, 29, 4}
maximum(a)

不一樣狀況下的返回值

  1. 若是將函數做爲單獨的語句執行,lua 會丟棄全部的返回值
  2. 若是將函數做爲表達式的一部分調用,只保留函數的第一個返回值
  3. 只有當函數是一系列表達式中的最後一個元素(或只有一個元素的時候),纔會獲取全部的返回值

一系列表達式的4種狀況

多重賦值
  1. 若是一個函數調用是最後(或僅有)的一個表達式,lua 會保留儘量多的返回值,用來匹配賦值的變量
  2. 若是一個函數沒有返回值或沒有返回足夠多的返回值,那麼 lua 會用 nil 來補充缺失的值
  3. 若是一個函數調用不是一系列表達式中的最後一個元素,就只能返回一個值
function foo() end
function foo1() return "a" end
function foo2() return "a", "b" end

-- 第一種狀況,最後(或僅有)的一個表達式
x, y = foo1() -- x = a, y = b
-- 第二種狀況,沒有返回值
x = foo() -- nil
-- 第二種狀況,沒有返回足夠多的返回值
x, y, z = foo1() -- x = a, y = b, z = nil
-- 第三種狀況,不是表達式中的最後一個元素
x, y = foo2(), 10 -- x = a, y = 10
函數調用時傳入的實參列表
  1. 若是一個函數調用做爲另外一個函數調用的最後一個(或僅有的)實參的時候,第一個函數的全部返回值都會做爲實參傳遞給另外一個函數
function foo() end
function foo1() return "a" end
function foo2() return "a", "b" end
-- 第四種狀況,做爲 print 函數中的最後一個(或僅有的)實參
print(foo()) -- nil
print(foo1()) -- "a"
print(foo2()) -- "a" "b"
print(foo1() .. "test") -- "atest"
print(foo2() .. "test") -- "atest"
table 構造式
  1. table 構造式會完整接收一個函數調用的全部結果,即不會由任何數量方面的調整
  2. 但這種行爲,只有當一個函數調用做爲最後一個元素時才發生
  3. 其餘位置上的函數調用老是隻產生一個結果值
function foo() end
function foo1() return "a" end
function foo2() return "a", "b" end
-- 函數調用是 table 中的最後一個元素
a = {foo2()} -- a = {"a", "b"}
a = {foo2(), 10} -- a = {"a", 10}
return 語句
  1. 將函數調用放入一對圓括號 () 中,使其只返回一個結果
  2. return 語句後面的內容不須要 () 圓括號
  3. 若是強行加上則會使一個多返回值的函數,強制其只返回一個 return(f())
function foo0() end
function foo1() return "a" end
function foo2() return "a", "b" end
function foo(i)
    if i == 0 then return foo0() 
        elseif i == 1 then return foo1() 
        elseif i == 2 then return foo2() 
    end
end
print(foo(1)) -- a
print(foo(2)) -- a, b
print(foo(0)) -- 無返回值,在交互模式中會是一個空行

-- () 包裹
print((foo(1)) -- a
print((foo(2)) -- a
print((foo(0)) -- nil ,應該是強制返回了一個未初始化的值,由於 foo0() 沒有返回值

unpack 函數

  1. 接收一個數組做爲參數
  2. 並從下標 1 開始返回該數組的全部元素
  3. 這個預約義函數由 C 語言編寫
print(unpack{10, 20, 30}) -- 10 20 30
a, b = unpack{10, 20, 30}  -- a = 10, b = 20
  1. 用於泛型調用
  2. 泛型調用就是能夠以任何實參來調用任何函數
-- 調用任意函數 f, 而全部的參數都在數組 a 中
-- unpack 將返回 a 中的全部值,這些值做爲 f 的實參
f(unpack(a)) 
f = string.find
a = {"hello", "ll"}
f(unpack(a)) -- 3 4 等效於 string.find("hello", "ll")

用 lua 遞歸實現 unpack

function unpack(t, i)
    i = i or 1
    if t[i] then
        return t[i], unpack(t, i + 1)
    end
end

變長參數

  1. lua 中的函數能夠接收不一樣數量的實參
  2. 當這個函數被調用時,它的全部參數都會被收集到一塊兒
  3. 這部分收集起來的實參稱爲這個函數的「變長參數」
  4. ... 三個點表示該函數接收不一樣數量的實參
  5. 一個函數要訪問它的變長參數時,須要用 ... 三個點,此時 ... 三個點是做爲一個表達式使用的
  6. 表達式 ... 三個點的行爲相似一個具備多重返回值的函數,它返回的是當前函數的全部變長參數
  7. 具備變長參數的函數也能夠擁有任意數量的固定參數
  8. 但固定參數必定要在變長參數以前
  9. 當變長參數中包含 nil ,則須要用 select 訪問變長參數
  10. 調用 select 時,必須傳入一個固定參數 selector (選擇開關) 和一系列變長參數
  11. 若是 selector 爲數字 n ,那麼 select 返回它的第 n 個可變實參
  12. 不然,select 只能爲字符串 "#" ,這樣 select 會返回變長參數的總數,包括 nil
-- 返回全部參數的和
function add(...)
    local s = 0
    for i, v in ipairs{...} do -- 表達式{...}表示一個由變長參數構成的數組
           s = s + v
    end
    return s
end
print(add(3, 4, 5, 100)) -- 115

-- 調試技巧 ,相似與直接調用函數 foo ,但在調用 foo 前先調用 print 打印其全部的實參
function foo1(...)
    print("calling foo:", ...)
    return foo(...)
end


-- 獲取函數的實參列表
function foo(a, b, c) end
function foo(...)
        local a, b, c = ...
end
-- 格式化文本 string.format ,輸出文本 io.write
-- 固定參數必定要在變長參數以前
function fwrite(fmt, ...)
    return io.write(string.format(fmt, ...))
end
fwrite() -- fmt = nil
fwrite("a") -- fmt = a 
fwrite("%d%d", 4, 5) -- fmt = "%d%d" , 變長參數  = 4, 5

for i = 1, select('#', ...) do
    local arg = select('#', ...)
    <循環體>
end

具名參數

  1. lua 中的參數傳遞機制是具備 「位置性」的
  2. 就是說在調用一個函數時,實參是經過它在參數表中的位置與形參匹配起來的
  3. 第一個實參的值與第一個形參相匹配,依此類推
  4. 定義:經過名稱來指定實參
  5. 可將全部的實參組織到一個 table 中,並將這個 table 做爲惟一的實參傳給函數
  6. lua 中特殊的函數調用語法,當實參只有一個 table 構造式時,函數調用中的圓括號 () 是無關緊要的
os.rename  -- 文件更名,但願達到的效果 os.rename(old = "temp.lua", new = "temp1.lua")
-- lua 不支持註釋的寫法
rename = {old = "temp.lua", new = "temp1.lua"}
function rename (arg)
    return os.rename(arg.old, arg.new)
end

x = Window{x = 0, y = 0, width = 300, height = 200, title = "Lua", background = "blue", border = "true"}

-- Window 函數根據要求檢查必填參數,或爲某些函數添加默認值
-- 假設 _Window 是真正用於建立新窗口的函數,要求全部參數以正確次序傳入
function Window(options)
    if type(options.title) ~= "string" then
        error("no title")
    elseif type(options.width) ~= "number" then
        error("no width")
    elseif type(options.height) ~= "height" then
        error("no height")
    end
    _Window(options.title,
        options.x or 0 -- 默認值
        options.y or 0 -- 默認值
        options.width, options.height,
        options.background or "white" -- 默認值
        options.border -- 默認值爲 false(nil)
    )
end

由於,目前只學到第五章函數篇,因此只有前五章的複習彙總,很基礎,也很重要,也祝願你們能夠踏踏實實地打好地基。測試

相關文章
相關標籤/搜索