欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Lua中的元表和元方法

 更新時間:2023年09月11日 08:40:04   作者:江澎涌  
Lua中的元表(Metatable)和元方法(Metamethods)是Lua語言中的重要概念,它們允許我們對對象和操作進行自定義,本文講給大家詳細介紹一下Lua中的元表和元方法,需要的朋友可以參考下

一、元表

元表可以修改一個值在面對一個未知操作時的行為,Lua 中使用 table 作為元表的承載。

元表只能給出預先定義的操作集合的行為,比類會更加受限制,不支持繼承。

Lua 每一個值都可以有元表

  • 表和用戶數(shù)據(jù)類型都具有各自獨立的元表;
  • 其他類型的值則共享對應類型所屬的同一個元表;

二、元表的設置

1、類型的原始元表

Lua 中,元表的設置只能針對 table ,其他類型都不能設置。

table 的初始化元表為 nil ,即沒有設置元表,只能通過 setmetatable 進行設置,多個 table 可以共享一個 table 作為元表(當然也可以使用他自己作為自己的元表,因為他自身也是一個 table)

Lua 只有 string 初始化了元表,而且是針對了所有的字符串,即 string 都是同一個元表。其他的類型為 nil 。

print("表的初始值", getmetatable({}))           --> 表的初始值	nil
print("整型的初始值", getmetatable(10))         --> 整型的初始值	nil
print("浮點型的初始值", getmetatable(10.0))      --> 浮點型的初始值	nil
--- 通過打印可以看到兩個字符串的元表是同一個
print("字符串的初始值", getmetatable("江澎涌"))   --> 字符串的初始值	table: 0x600000b14640
print("字符串的初始值", getmetatable("jiangpengyong"))  --> 字符串的初始值	table: 0x600000b14640
print("布爾型的初始值", getmetatable(true))     --> 布爾型的初始值	nil
print("nil的初始值", getmetatable(nil))         --> nil的初始值	nil
function sayHello()  end
print("函數(shù)的初始值", getmetatable(sayHello))   --> 函數(shù)的初始值	nil

2、設置元表和獲取元表

2-1、setmetatable(table, metatable)

給表 table 設置元表 metatable

參數(shù)

  • table:要被設置元表的表
  • metabale:元表,如果值為 nil ,則表明要刪除 table 的原有元表。如果原來的元表有 __metatable 字段,則不能再設置元表,否則會拋出異常 cannot change a protected metatable

__metatable 會在下面的 “表相關方法” 小節(jié)分享

返回值:

返回被設置元表的表,就是參數(shù) table

2-2、getmetatable(object)

如果 object 沒有元表,則返回 nil

如果對象 Object 有元表,且該元表有一個 "__metatable" 字段,則返回關聯(lián)的值。否則,返回給定對象 Object 的元表

2-3、舉個例子

local oriTable = {}
local metaTable = {}
print(setmetatable(oriTable, metaTable), oriTable, metaTable)       --> table: 0x600001ac0840	table: 0x600001ac0840
print(getmetatable(oriTable), metaTable)                            --> table: 0x600001ac0900	table: 0x600001ac0900

給元表帶有 __metatable 字段的表,設置新的元表,則會拋出異常(見下圖)

t2 = { c = 1 }
t2.__metatable = { a = 1 }
s1 = {}
setmetatable(s1, t2)
print('getmetatable(s1)["a"]', getmetatable(s1)["a"])           --> getmetatable(s1)["a"]	1
-- 此處會拋出異常:cannot change a protected metatable
print(setmetatable(s1, {}))

三、元表方法

1、具有的元方法

元表方法方法很像 kotlin 中的操作符方法

1-1、算術運算符

元表方法含義
__add加法
__mul乘法
__sub減法
__div除法
__floorfloor除法
__unm負數(shù)
__mod取模
__pow冪運算
__band按位與
__bor按位或
__bxor按位異或
__bnot按位取反
__shl向左移
__shr向右移
__concat定義連接運算符

1-2、關系運算符

元表方法含義
__eq等于
__lt小于
__le小于等于

值得注意: ~=、a > b、a >= b 沒有對應的元方法,會被轉為如下

  • a ~= b 會被轉為 not( a == b)
  • a > b 會被轉為 b < a
  • a >= b 會被轉為 b <= a

關系運算符遇到兩個不同類型的對象,則會直接返回 false ,不會進行搜尋任何的元方法

1-3、庫相關方法

元表方法含義
__tostring當調(diào)用 tostring 時,會先檢查值是否有一個元方法 __tostring ,有則會先使用。
__metatable使用該元方法可以保護元表,用戶無法獲取也無法修改該元表。當元表設置了 __metatable 的字段,則 getmetatable 會返回這個字段的值,而 setmetatable 則會引發(fā)錯誤
__pairs從 Lua 5.2 開始,當元表擁有一個 __pairs 的元方法時,pairs 會調(diào)用這個元方法來完成遍歷

1-4、表相關方法

元表方法含義
__index一旦訪問 table 中不存在的字段,正常情況下會返回 nil 。如果設置了這個元表方法,則會調(diào)用自身元表對應的該 __index 元方法,并以被調(diào)用的表(即此處的 table ,不是元表)和鍵作為參,進行調(diào)用。也可以給 __index 設置一個 table,這樣就會直接在這table 中查詢,速度比方法稍快??梢酝ㄟ^ rawget 獲取原始數(shù)據(jù),不考慮元表。
__newindex當調(diào)用 table 進行索引賦值時,如果設置了該元表方法,則會使用被調(diào)用的表(即此處的 table ,不是元表),鍵和值作為參,調(diào)用該方法。同樣也可以給 __newindex 設置一個表,則會將值直接存至該表。可以通過 rawset(talbe, key, value) 相當于 table[key] = value 進行直接對 table 的賦值,不考慮元表。
__len獲取 table 的長度時,會調(diào)用該方法,獲取長度

__index__newindex 的異同

  • 相同點:兩個函數(shù)都是發(fā)生在 table 中沒有對應的 key 時觸發(fā)
  • 不同點:當前需要的索引沒有對應的值時則調(diào)用 __index ,如果 table 設置值時,則調(diào)用 __newindex

2、元方法的搜索

如果兩個變量相加,搜索規(guī)則如下:

  • 先查看第一個值是否有元表,并且是否存在所需元方法,如果存在則使用該元方法,此時第二個值的元方法被忽略。否則進入下一條
  • 查看第二個值是否有元表,并且是否存在所需的元方法,如果有則進行使用。否則進入第三條
  • 拋出異常

3、舉個例子

這里元方法比較多,就不一一粘貼代碼了,不然會讓文章非常冗長。建議各位童鞋們移步 github clone 下代碼自行運行一下會更加深刻理解。

“算術運算符” 、 “關系運算符”、“庫相關方法” 相關的代碼 可以查看以下的代碼:

集合.lua:github.com/zincPower/l…

集合調(diào)用.lua:github.com/zincPower/l…

“表相關方法” 相關的代碼

表相關元方法.lua:github.com/zincPower/l…

四、寫在最后

以上就是詳解Lua中的元表和元方法的詳細內(nèi)容,更多關于Lua元表和元方法的資料請關注腳本之家其它相關文章!

相關文章

  • Lua獲取文件長度和判斷文件是否存在函數(shù)分享

    Lua獲取文件長度和判斷文件是否存在函數(shù)分享

    這篇文章主要介紹了Lua獲取文件長度和判斷文件是否存在函數(shù)分享,需要的朋友可以參考下
    2015-04-04
  • 解析Lua中的全局環(huán)境、包、模塊組織結構

    解析Lua中的全局環(huán)境、包、模塊組織結構

    Lua中也擁有和Python世界相似的代碼的作用范圍和組織方式,下面我們就來簡單解析Lua中的全局環(huán)境、包、模塊組織結構,需要的朋友可以參考下
    2016-06-06
  • Lua中的函數(shù)知識總結

    Lua中的函數(shù)知識總結

    這篇文章主要介紹了Lua中的函數(shù)知識總結,本文講解了函數(shù)的一些基礎知識、多重返回值問題、變長參數(shù)、內(nèi)嵌函數(shù)等內(nèi)容,需要的朋友可以參考下
    2014-09-09
  • Lua和C++的通信流程分解

    Lua和C++的通信流程分解

    這篇文章主要介紹了Lua和C++的通信流程分解,本文用一張圖講解了Lua和C++之間的通信流程,并對每一步做了分解,需要的朋友可以參考下
    2014-09-09
  • Lua一維數(shù)組與多維數(shù)組的使用示例

    Lua一維數(shù)組與多維數(shù)組的使用示例

    今天小編就為大家分享一篇關于Lua一維數(shù)組與多維數(shù)組的使用示例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Lua中的迭代器和泛型for實例

    Lua中的迭代器和泛型for實例

    這篇文章主要介紹了Lua中的迭代器和泛型for實例,本文還講解了無狀態(tài)迭代器,需要的朋友可以參考下
    2014-09-09
  • lua+love2d制作的2048游戲

    lua+love2d制作的2048游戲

    前面給大家分享的是一個超級簡單版的使用lua實現(xiàn)的2048小游戲的代碼,今天我們加上love2d游戲引擎,制作PC版的2048游戲。小伙伴們仔細讀讀本文吧。
    2015-03-03
  • Lua性能優(yōu)化技巧(三):關于表

    Lua性能優(yōu)化技巧(三):關于表

    這篇文章主要介紹了Lua性能優(yōu)化技巧(三):關于表,本文講解了一些關于表的優(yōu)化技巧,需要的朋友可以參考下
    2015-04-04
  • Lua中的協(xié)同程序之resume-yield間的數(shù)據(jù)返回研究

    Lua中的協(xié)同程序之resume-yield間的數(shù)據(jù)返回研究

    這篇文章主要介紹了Lua中的協(xié)同程序之resume-yield間的數(shù)據(jù)返回研究本文講解了resume的參數(shù)、resume函數(shù)的第二個返回值、yield的返回值等內(nèi)容,需要的朋友可以參考下
    2014-09-09
  • Lua腳本實現(xiàn)遞歸刪除一個文件夾

    Lua腳本實現(xiàn)遞歸刪除一個文件夾

    這篇文章主要介紹了Lua腳本實現(xiàn)遞歸刪除一個文件夾,本文給出了C++和Lua兩個版本的實現(xiàn)代碼,需要的朋友可以參考下
    2015-05-05

最新評論