Redis基礎知識(學習筆記21--Lua 指令碼語言2)

东山絮柳仔發表於2024-09-08

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】

相關文章