4.2 迭代器
Lua提供了兩個迭代器pairs(table) 與 ipairs(table)。這兩個迭代器通常會應用於泛型for迴圈中,用於遍歷指定的table。這兩個迭代器的不同是:
- ipairs(table):僅會迭代指定table中的陣列元素。
- pairs(table) :會迭代整個table元素,無論是陣列元素,還是key-value。
4.3 模組
模組是Lua中特有的一種資料結構。從 Lua 5.1 開始,Lua加入了標準的模組管理機制,可以把一些公用的程式碼放在一個檔案裡,以 API 介面的形式在其他地方呼叫,有利於程式碼的重用和降低程式碼耦合度。
模組主要由 table 組成。在 table 中 新增相應的變數、函式,最後檔案返回該 table 即可。如果其它檔案中需要使用該模組,只需透過 require 將該模組匯入即可。
4.4 元表與元方法
元表,即 Lua 中普通 table 的後設資料表,而元方法則是元表中定義的普通表的預設行為。 Lua 中的每個普通 table 都為其定義一個元表,用於擴充套件該普通 table 的行為功能。例如,對於 table 與數值相加的行為, Lua 中是沒有定義的,但使用者可透過 為其指定元表來擴充套件這種行為;再如,使用者訪問不存在的 table 元素, Lua 預設返回的是 nil,但使用者可能並不知道發生了什麼。此時可以透過為該 table 指定元素來擴充套件該行為:給使用者提示資訊,並返回使用者指定的值。
(1)重要函式
元表中有兩個重要函式:
- setmetatable(table,metatable)::將metatable指定為普通table的元表。
- getmetatable(table):獲取指定普通表 table 的元表。
(2)__index 元方法
當使用者在對 table 進行讀取訪問時,如果訪問的陣列索引或key 不存在,那麼系統就會自動呼叫元表的 __index 元方法。該重寫的方法可以是一個函式,也可以是另一個表。如果重寫的__index 元方法是函式,且有返回值,則直接返回;如果沒有返回值,則返回nul。
(3)__newindex元方法
當使用者為 table 中一個不存在的索引或key賦值時,就會自動呼叫元表的__newindex 元方法。該重寫的方法可以是一個函式,也可以是另一個表。如果重寫的__newindex元方法是函式,且有返回值,則直接返回;如果沒有,則返回nil。
(4)運算子元方法
如果要為一個表擴充套件加號(+)、減號(-)、等於(==)、小於(<)等運算功能,則可重寫相應的元方法。
例如,如果要為一個table擴充套件加號(+)運算功能,則可以重寫該table元表的__add元方法,而具體的運算規則,則是定義在該重寫的元方法中的。這樣,當一個table在進行加法(+)運算時,就會自動呼叫其元表的__add元方法。
類似於加法操作的其它操作,Lua中還有:
元方法 | 說明 | 元方法 | 說明 |
__add | 加法,+ | __band | 按位與,& |
__sub | 減法,- | __bor | 按位或,| |
__mul | 乘法,* | __bxor | 按位異或,~ |
__div | 除法,/ | __bnot | 按位非,~ |
__mod | 取模,% | __shl | 按位左移,<< |
__pow | 次冪,^ | __shr | 按位右移,>> |
__unm | 取反,- | __eq | 等於,== |
__idiv | 取整除法,// | __it | 小於,< |
__concat | 字串連線,... | __lt | 大於,> |
__len | 字串長度,# |
(5)__tostring 元方法
直接輸出一個table,其輸出的內容為型別與table的存放地址。如果想讓其輸出table中的內容,可重寫__tostring元方法。
(6)__call元方法
當將一個table以函式形式來使用時,系統會自動呼叫重寫的__call元方法。該用法主要時可以簡化對table的相關操作,將對table的操作與函式直接結合。
(7)元表單獨定義
為了便於管理和複用,可以將元素單獨定義為一個檔案。該檔案中僅可定義一個元表,且一般檔名與元表名稱相同。
若一個檔案要使用其它檔案中定義的元表,只需使用 require"元表檔名“ 即可將元表匯入使用。
如果使用者想擴充套件該元表而又不想修改元表檔案,則可在使用者自己檔案中重寫其相應功能的元方法即可。
5.物件導向
Lua 中沒有類的概念,但透過table、function 與元表可以模擬和構造出具有類這樣功能的結構。
(1)簡單物件的建立
Lua 中透過table 與 function可以建立出一個簡單Lua物件:table為Lua物件賦予屬性,透過function為Lua物件賦予行為,即方法。
(2)類的建立
Lua 中使用table 、function與元表可以定義出類:使用一個表作為基礎類,使用一個function作為該基礎類的new()方法。在該new()方法中建立出一個空表,再為該空表指定一個元表。該元表重寫__index元方法,且將基礎表指定為重寫的__index元方法。由於new()中的表是空表,所以使用者訪問的所有key都會從基礎類(表)中查詢。
6.協同執行緒與協同函式
(1)協同執行緒
Lua 中有一種特殊的執行緒,稱為coroutine,協同執行緒,簡稱協程。其可以再執行時暫停執行,然後轉去執行其它執行緒,然後還可以返回再繼續執行沒有執行完畢的內容。即可以”走走停停,停停再走走“。
協同執行緒也稱為協作多執行緒,在Lua中表示獨立的執行執行緒。任意時刻只會有一個協程執行,而不會出現多個協程同時執行的情況。
協同執行緒的型別為thread,其啟動、暫停、重啟等,都需要透過函式來控制。下表是用於控制協同執行緒的基本方法。
方法 | 描述 |
create(function) | 建立一個協同執行緒例項,即返回的是thread型別。引數是一個function。其需要透過resume()來啟動協同執行緒的執行。 |
resume(thread,...) | 啟動指定的協同執行緒的執行,使其 從開始處或前面掛起處開始執行。可以向create()的內建函式傳遞相應的引數。如果內建函式具有返回值,resume()會全部接收並返回。 |
running() | 返回正在執行的協同執行緒例項,即thread型別值。 |
yield() | 掛起協同執行緒,並將協同執行緒設定為掛起狀態。resume()可從掛起處重啟被掛起的協同執行緒。 |
status(thread) | 檢視協同執行緒的狀態。狀態有三種:執行態running,掛起態suspended,消亡態dead。 |
colse() | 關閉協同執行緒 |
wrap(function) | 建立一個協同執行緒,返回的是function型別。一旦呼叫該函式就會建立並執行一個協同執行緒例項。 |
示例 1 ,無返回值
示例 2 ,有返回值
(2)協同函式
協同執行緒可以單獨建立執行,也可以透過協同函式的呼叫啟動執行。使用coroutine的wrap()函式建立的就是協同函式,其型別為function。
由於協同函式的本質就是函式,所以,協同函式的呼叫方式就是標準的函式呼叫方式。只不過,協同函式的呼叫會啟動其內建的協同執行緒。
示例如下:
也可以透過resume的方式開始掛起的協程。
7. 檔案IO
Lua 中提供了大量對檔案進行IO操作的函式。這些函式分為兩類:靜態函式和例項函式。所謂靜態函式是指透過io.xxx()方法對檔案進行操作的函式,而例項函式是透過Lua中物件導向方式操作的函式。
7.1 常見靜態函式
(1)io.open()
【格式】io.open(filename [,mode])
【解析】以指定模式開啟指定檔案,返回要開啟檔案的控制代碼,就是一個物件。其中模式mode有三種,但同時還可配合兩個符號使用:
- r:只讀,預設模式。
- w:只寫,寫入內容會覆蓋檔案原有內容。
- a:只寫,以追加方式寫入內容。
- +:增加符,在r+、w+、a+均變為了讀寫。
- b:二進位制表示符。如果要操作的檔案為二進位制檔案,則需要變為rb、wb、ab。
(2)io.input()
【格式】:io.input(file)
【解析】:指定要讀取的檔案。
(3)io.output()
【格式】:io.output(file)
【解析】:指定要寫入的檔案。
(4)io.read()
【格式】:io.read([format])
【解析】:以指定格式讀取io.input()中指定的輸入檔案。其中format格式有:
- *I:從當前位置的下一個位置開始讀取整個行,預設格式。
- *n:讀取下一個數字,其將作為浮點數或整數。
- *a:從當前位置的下一個位置開始讀取整個檔案。
- number:這是一個數字,表示要讀取的字元的個數。
(5)io.write()
【格式】:io.write(data)
【解析】:將指定的資料data寫入到io.output()中指定的輸出檔案。
示例1
示例2
7.2 常見例項函式
(1)file:read()
這裡的file使用的是io.open()函式返回的file,其實際就是Lua中的一個物件。其用法與io.read()的相同。
示例:
(2)file:write()
用法與io.write()相同。
示例:
注意寫入的字串前面的 \n 表示換行。
(3)file:seek()
【格式】file:seek(|whence[,offset])
【解析】該函式用於獲取或者設定檔案讀寫指標的當前位置。位置從1開始計數,除檔案最後一行外,每行都有行結束符,其會佔兩個字元位置。位置0表示檔案第一個位置的前面位置。
當seek()為無參時會返回讀寫指標的當前位置。引數whence的值有三種,表示將指標定位的不同位置。而offset則表示相對於whence指定位置的偏移量,offset的預設值為0,為正表示向後偏移,為負表示向前偏移。
- set:表示將指標定位到檔案開頭處,即0位置處。
- cur:表示指標保持當前位置不變,預設值。
- end:表示將指標定位到檔案結尾處。
學習筆記--參閱特別宣告
1.【Redis影片從入門到高階】
【https://www.bilibili.com/video/BV1U24y1y7jF?p=11&vd_source=0e347fbc6c2b049143afaa5a15abfc1c】