天天看點

Lua 基礎

【轉載請注明出處】: https://developer.aliyun.com/article/758555

基本文法

注釋

  • 兩個減号是單行注釋:

    --注釋

  • 多行注釋

    `--[[ 注釋 --]]

`

标示符

标示符以字母或下劃線 _ 開頭,加上字母、下劃線或數字組成。

最好不要使用下劃線加大寫字母的标示符,因為Lua的保留字也是這樣的。

關鍵詞

以下列出了 Lua 的保留關鍵字。保留關鍵字不能作為常量或變量或其他使用者自定義标示符:

and 、break 、 do 、 else 、 elseif 、end、false 、for 、 function 、if 、in 、 local 、nil 、 not 、 or 、 repeat 、return 、 then 、true 、until 、while

一般約定,以下劃線開頭連接配接一串大寫字母的名字(比如 _VERSION)被保留用于 Lua 内部全局變量。

全局變量

在預設情況下,變量總是認為是全局的。

Lua 資料類型

Lua中有8個基本類型分别為:nil、boolean、number、string、userdata、function、thread和table。

| 資料類型 | 描述 | 說明 |

| - | - | - |

| nil | 這個最簡單,隻有值nil屬于該類,表示一個無效值(在條件表達式中相當于false)。| nil 作比較時應該加上雙引号 |

| boolean | 包含兩個值:false和true。| Lua 把 false 和 nil 看作是"假",其他的都為"真" |

| number | 表示雙精度類型的實浮點數 | |

| string | 字元串由一對雙引号或單引号來表示 | 也可以用 2 個方括号 "[[]]" 來表示"一塊"字元串。

使用 # 來計算字元串的長度

在對一個數字字元串上進行算術操作時,Lua 會嘗試将這個數字字元串轉成一個數字|

| function | 由 C 或 Lua 編寫的函數 | |

| userdata | 表示任意存儲在變量中的C資料結構 | |

| thread | 表示執行的獨立線路,用于執行協同程式 | |

| table | Lua 中的表(table)其實是一個"關聯數組"(associative arrays),數組的索引可以是數字或者是字元串。在 Lua 裡,table 的建立是通過"構造表達式"來完成,最簡單構造表達式是{},用來建立一個空表。 | |

可以使用type函數測試給定變量或者值的類型。

Lua 變量

Lua 變量有三種類型:全局變量、局部變量、表中的域。

Lua 中的變量全是全局變量,那怕是語句塊或是函數裡,除非用 local 顯式聲明為局部變量。

局部變量的作用域為從聲明位置開始到所在語句塊結束。

指派語句

--指派是改變一個變量的值和改變表域的最基本的方法。
a = "hello" .. "world"
t.n = t.n + 1

--Lua可以對多個變量同時指派,變量清單和值清單的各個元素用逗号分開,指派語句右邊的值會依次賦給左邊的變量。
a, b = 10, 2*x     -- 等價于  a=10; b=2*x           

當變量個數和值的個數不一緻時,Lua會一直以變量個數為基礎采取以下政策:

  • 變量個數 > 值的個數 按變量個數補足nil
  • 變量個數 < 值的個數 多餘的值會被忽略

索引

對 table 的索引使用方括号 []。Lua 也提供了 . 操作。

t[i]
t.i     -- 當索引為字元串類型時的一種簡化寫法           

Lua 循環

Lua 語言提供了以下幾種循環處理方式:

| 循環類型 | 描述 |

| - | - |

| while 循環 |在條件為 true 時,讓程式重複地執行某些語句。執行語句前會先檢查條件是否為 true。 |

| for 循環| 重複執行指定語句,重複次數可在 for 語句中控制。 |

| repeat...until| 重複執行循環,直到 指定的條件為真時為止 |

| 循環嵌套 | 可以在循環内嵌套一個或多個循環語句(while do ... end;for ... do ... end;repeat ... until;) |

while 循環

while(condition)
do
   statements
end           

數值for循環

Lua 程式設計語言中數值for循環文法格式:

for var=exp1,exp2,exp3 do  
    statements
end             

var 從 exp1 變化到 exp2,每次變化以 exp3 為步長遞增 var,并執行一次 "執行體"。exp3 是可選的,如果不指定,預設為1。

泛型for循環

泛型 for 循環通過一個疊代器函數來周遊所有值,類似 java 中的 foreach 語句。

for i, v in ipairs(value) do
     statements
end            

i是數組索引值,v是對應索引的數組元素值。ipairs是Lua提供的一個疊代器函數,用來疊代數組。

repeat...until 循環

repeat
   statements
until( condition )           

Lua 流程控制

Lua 提供了以下控制結構語句:

| 語句 | 描述 |

| - | - |

| if 語句| if 語句 由一個布爾表達式作為條件判斷,其後緊跟其他語句組成。 |

| if...else 語句 | if 語句 可以與 else 語句搭配使用, 在 if 條件表達式為 false 時執行 else 語句代碼。 |

| if 嵌套語句| 你可以在if 或 else if中使用一個或多個 if 或 else if 語句 。 |

if 語句

if(condition)
then
   statements
end           

if...else 語句

if(condition)
then
  statements1
else
   statements2
end           

if...elseif...else 語句

if(condition1)
then
  statements1
elseif(condition2) 
then
   statements2
else 
   statements3
end           

Lua 函數

函數定義

optional_function_scope function function_name( argument1, argument2, argument3..., argumentn)
    function_body
    return result_params_comma_separated
end           
  • optional_function_scope: 該參數是可選的制定函數是全局函數還是局部函數,未設定該參數預設為全局函數,如果你需要設定函數為局部函數需要使用關鍵字 local。
  • function_name: 指定函數名稱。
  • argument1, argument2, argument3..., argumentn: 函數參數,多個參數以逗号隔開,函數也可以不帶參數。
  • function_body: 函數體,函數中需要執行的代碼語句塊。
  • result_params_comma_separated: 函數傳回值,Lua語言函數可以傳回多個值,每個值以逗号隔開。

多傳回值

Lua函數中,在return後列出要傳回的值的清單即可傳回多值。

可變參數

Lua 函數可以接受可變數目的參數,和 C 語言類似,在函數參數清單中使用三點 ... 表示函數有可變的參數。

有時候可能需要幾個固定參數加上可變參數,則固定參數必須放在變長參數之前。

通常在周遊變長參數的時候隻需要使用 {…},然而變長參數可能會包含一些 nil,那麼就可以用 select 函數來通路變長參數了:select('#', …) 或者 select(n, …)

  • select('#', …) 傳回可變參數的長度
  • select(n, …) 傳回它的第n個可變實參
function average(...)
   result = 0
   local arg={...}    
   for i,v in ipairs(arg) do
      result = result + v
   end 
   return result/#arg    --或者 return result/select("#",...)
end           

Lua 運算符

算術運算符

| 操作符 | 描述 |

| + | 加法 |

| - | 減法/負号 |

| * | 乘法 |

| / | 除法 |

| % | 取餘 |

| ^ | 乘幂 |

關系運算符

| 操作符 | 描述 |

| == |等于,檢測兩個值是否相等,相等傳回 true,否則傳回 false |

| ~= | 不等于,檢測兩個值是否相等,相等傳回 false,否則傳回 true |

| > | 大于,如果左邊的值大于右邊的值,傳回 true,否則傳回 false |

| < | 小于,如果左邊的值大于右邊的值,傳回 false,否則傳回 true |

| >= | 大于等于,如果左邊的值大于等于右邊的值,傳回 true,否則傳回 false |

| <= | 小于等于, 如果左邊的值小于等于右邊的值,傳回 true,否則傳回 false|

邏輯運算符

| 操作符 | 描述 |

| and |邏輯與操作符。|

| or | 邏輯或操作符。|

| not | 邏輯非操作符。|

其他運算符

|操作符 | 描述 |

| .. | 連接配接兩個字元串 |

| # | 一進制運算符,傳回字元串或表的長度。 |

運算符優先級

|從高到低的順序|

| - |

| ^ |

| not - (unary) |

| * / |

| + - |

| .. |

| < > <= >= ~= == |

| and |

| or |

除了^和..外所有的二進制運算符都是左連接配接的。

Lua 字元串

Lua 語言中字元串可以使用以下三種方式來表示:

  • 單引号間的一串字元。
  • 雙引号間的一串字元。
  • [[和]]間的一串字元。

字元串操作

| 方法 | 用途 |

| string.upper(argument) | 全部轉為大寫 |

| string.lower(argument) | 全部轉為小寫 |

| string.gsub(mainString,findString,replaceString,num) |在字元串中替換,mainString為要替換的字元串, findString 為被替換的字元,replaceString 要替換成的字元,num 替換次數(可以忽略,則全部替換)|

| string.find (mainString, findString, [startIndex, [endIndex]]) | 在一個指定的目标字元串中搜尋指定的内容(第三個參數為索引),傳回其具體位置。不存在則傳回 nil。|

| string.reverse(arg) | 字元串反轉 |

| string.format(...) | 傳回一個類似printf的格式化字元串 |

| string.char(ASCIICodes...) | 将ASCII碼轉成字元并連接配接|

| string.byte(str[,index]) | 将指定的字元轉成ASCII碼(預設第一個字元)|

| string.len(arg) | 計算字元串長度 |

| string.rep(str, n) | 傳回字元串string的n個拷貝 |

| .. | 連結兩個字元串 |

| string.gmatch(str, pattern) | 傳回一個疊代器函數,每一次調用這個函數,傳回一個在字元串 str 找到的下一個符合 pattern 描述的子串。如果參數 pattern 描述的字元串沒有找到,疊代函數傳回nil。|

|string.match(str, pattern, init) | string.match()隻尋找源字串str中的第一個配對. 參數init可選, 指定搜尋過程的起點, 預設為1。

在成功配對時, 函數将傳回配對表達式中的所有捕獲結果; 如果沒有設定捕獲标記, 則傳回整個配對字元串. 當沒有成功的配對時, 傳回nil。 |

Lua 數組

Lua 數組的索引鍵值可以使用整數表示,數組的大小不是固定的。

可以使用整數索引來通路數組元素,如果指定的索引沒有值則傳回nil。

Lua 索引值是以 1 為起始,但也可以指定 0 開始,除此之外還可以以負數為數組索引值。

Lua 疊代器

疊代器(iterator)是一種對象,它能夠用來周遊标準模闆庫容器中的部分或全部元素,每個疊代器對象代表容器中的确定的位址

在Lua中疊代器是一種支援指針類型的結構,它可以周遊集合的每一個元素。

泛型 for 疊代器

泛型 for 在自己内部儲存疊代函數,實際上它儲存三個值:疊代函數、狀态常量、控制變量。

泛型 for 疊代器提供了集合的 key/value 對,文法格式如下:

for k, v in pairs(t) do
    print(k, v)
end           

k, v為變量清單;pairs(t)為表達式清單。

Lua 的疊代器包含以下兩種類型:

無狀态的疊代器

無狀态的疊代器是指不保留任何狀态的疊代器,是以在循環中可以利用無狀态疊代器避免建立閉包花費額外的代價。

每一次疊代,疊代函數都是用兩個變量(狀态常量和控制變量)的值作為參數被調用,一個無狀态的疊代器隻利用這兩個值可以擷取下一個元素。

例如使用一個簡單的函數來實作疊代器,實作數字 n 的平方:

function square(iteratorMaxCount,currentNumber)
   if currentNumber<iteratorMaxCount
   then
      currentNumber = currentNumber+1
   return currentNumber, currentNumber*currentNumber
   end
end

for i,n in square,3,0
do
   print(i,n)
end           

多狀态的疊代器

很多情況下,疊代器需要儲存多個狀态資訊而不是簡單的狀态常量和控制變量,最簡單的方法是使用閉包,還有一種方法就是将所有的狀态資訊封裝到table内,将table作為疊代器的狀态常量,因為這種情況下可以将所有的資訊存放在table内,是以疊代函數通常不需要第二個參數。

例如:

function elementIterator (collection)
   local index = 0
   local count = #collection
   -- 閉包函數
   return function ()
      index = index + 1
      if index <= count
      then
         --  傳回疊代器的目前元素
         return collection[index]
      end
   end
end

array = {"Lua", "Tutorial"}
for element in elementIterator(array)
do
   print(element)
end           

Lua table(表)

table 是 Lua 的一種資料結構用來幫助我們建立不同的資料類型,如:數組、字典等。

Lua table 使用關聯型數組,可以用任意類型的值來作數組的索引,但這個值不能是 nil。

Lua table 是不固定大小的,可以根據自己需要進行擴容。

Lua也是通過table來解決子產品(module)、包(package)和對象(Object)的。 例如string.format表示使用"format"來索引table string。

| 方法 | 用途 |

| table.concat (tableObj [, separator [, startIndex [, endIndex]]]) | 列出tableObj從startIndex位置到endIndex位置的所有元素, 元素間以指定的分隔符(separator)隔開。|

| table.insert (tableObj, [index,] value) | 在tableObj的指定位置(index)插入值為value的一個元素。index參數可選, 預設為末尾。 |

| table.remove (tableObj [, index]) | 傳回tableObj位于index位置的元素。 其後的元素會被前移。index參數可選, 預設為table長度, 即從最後一個元素删起。 |

| table.sort (tableObj [, comp]) | 對給定的table進行升序排序。comp應滿足以下條件: 接受兩個參數(依次為a, b), 并傳回一個布爾型的值, 當a應該排在b前面時, 傳回true, 反之傳回false. |