最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Lua中的元表和元方法

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

一、元表

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

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

Lua 每一個(gè)值都可以有元表

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

二、元表的設(shè)置

1、類型的原始元表

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

table 的初始化元表為 nil ,即沒有設(shè)置元表,只能通過 setmetatable 進(jìn)行設(shè)置,多個(gè) table 可以共享一個(gè) table 作為元表(當(dāng)然也可以使用他自己作為自己的元表,因?yàn)樗陨硪彩且粋€(gè) table)

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

print("表的初始值", getmetatable({}))           --> 表的初始值	nil
print("整型的初始值", getmetatable(10))         --> 整型的初始值	nil
print("浮點(diǎn)型的初始值", getmetatable(10.0))      --> 浮點(diǎn)型的初始值	nil
--- 通過打印可以看到兩個(gè)字符串的元表是同一個(gè)
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、設(shè)置元表和獲取元表

2-1、setmetatable(table, metatable)

給表 table 設(shè)置元表 metatable

參數(shù)

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

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

返回值:

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

2-2、getmetatable(object)

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

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

2-3、舉個(gè)例子

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

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

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、算術(shù)運(yùn)算符

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

1-2、關(guān)系運(yùn)算符

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

值得注意: ~=a > b、a >= b 沒有對應(yīng)的元方法,會被轉(zhuǎn)為如下

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

關(guān)系運(yùn)算符遇到兩個(gè)不同類型的對象,則會直接返回 false ,不會進(jìn)行搜尋任何的元方法

1-3、庫相關(guān)方法

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

1-4、表相關(guān)方法

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

__index__newindex 的異同

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

2、元方法的搜索

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

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

3、舉個(gè)例子

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

“算術(shù)運(yùn)算符” 、 “關(guān)系運(yùn)算符”、“庫相關(guān)方法” 相關(guān)的代碼 可以查看以下的代碼:

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

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

“表相關(guān)方法” 相關(guān)的代碼

表相關(guān)元方法.lua:github.com/zincPower/l…

四、寫在最后

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

相關(guān)文章

  • Lua腳本語言基本語法快速入門教程

    Lua腳本語言基本語法快速入門教程

    這篇文章主要介紹了Lua腳本語言基本語法快速入門教程,本文是一個(gè)簡易教程,快速的羅列了常用語法,有一定編程語言基礎(chǔ)的同學(xué)更容易看芯片,需要的朋友可以參考下
    2015-07-07
  • Lua教程(十三):弱引用table

    Lua教程(十三):弱引用table

    這篇文章主要介紹了Lua教程(十三):弱引用table,一個(gè)table的弱引用類型是通過其元表的__mode字段來決定的,如果該值為包含字符"k",那么table就是key弱引用,如果包含"v",則是value弱引用,如果兩個(gè)字符均存在,就是key/value弱引用,需要的朋友可以參考下
    2015-04-04
  • C語言模塊回調(diào)Lua函數(shù)的兩種方法

    C語言模塊回調(diào)Lua函數(shù)的兩種方法

    這篇文章主要介紹了C語言模塊回調(diào)Lua函數(shù)的兩種方法,本文講解了C保存函數(shù)對象、C訪問Lua全局環(huán)境兩種方法,需要的朋友可以參考下
    2015-04-04
  • Lua中的迭代器淺析

    Lua中的迭代器淺析

    這篇文章主要介紹了Lua中的迭代器淺析,本文先是講解了什么是迭代器,然后給出了自己寫一個(gè)迭代器的示例,最后介紹了迭代器的調(diào)用方法,需要的朋友可以參考下
    2014-09-09
  • Lua教程(三):表達(dá)式和語句

    Lua教程(三):表達(dá)式和語句

    這篇文章主要介紹了Lua教程(三):表達(dá)式和語句,本文講解了算術(shù)操作符、關(guān)系操作符、邏輯操作符、字符串連接、table構(gòu)造器、控制結(jié)構(gòu)等內(nèi)容,需要的朋友可以參考下
    2015-04-04
  • Lua調(diào)用自定義C模塊

    Lua調(diào)用自定義C模塊

    Lua可以調(diào)用C函數(shù)的能力將極大的提高Lua的可擴(kuò)展性和可用性。對于有些和操作系統(tǒng)相關(guān)的功能,或者是對效率要求較高的模塊,我們完全可以通過C函數(shù)來實(shí)現(xiàn),之后再通過Lua調(diào)用指定的C函數(shù)。對于那些可被Lua調(diào)用的C函數(shù)而言,其接口必須遵循Lua要求的形式
    2015-09-09
  • Lua 數(shù)學(xué)庫的所有函數(shù)功能作用一覽

    Lua 數(shù)學(xué)庫的所有函數(shù)功能作用一覽

    這篇文章主要介紹了Lua 數(shù)學(xué)庫的所有函數(shù)功能作用一覽,本文羅列了lua數(shù)學(xué)庫的所有函數(shù),并對每個(gè)函數(shù)的功能作用做了簡短描述,需要的朋友可以參考下
    2015-06-06
  • 簡單講解Lua中的垃圾回收機(jī)制

    簡單講解Lua中的垃圾回收機(jī)制

    這篇文章主要介紹了Lua中的垃圾回收機(jī)制,自動的垃圾回收是Lua的重要特性之一,需要的朋友可以參考下
    2015-05-05
  • Lua腳本調(diào)用外部腳本

    Lua腳本調(diào)用外部腳本

    在游戲腳本開發(fā)中,我們往往會發(fā)現(xiàn)腳本量非常大,而且我們經(jīng)常會在一些核心腳本文件中定義常用的功能函數(shù),但是Lua腳本沒有提供include關(guān)鍵詞,那又是怎樣調(diào)用外部函數(shù)的呢?如何實(shí)現(xiàn)腳本的Include功能?
    2014-09-09
  • Lua利用cjson讀寫json示例分享

    Lua利用cjson讀寫json示例分享

    本文結(jié)合本人的實(shí)際使用經(jīng)驗(yàn)和代碼示例,介紹如何在Lua中對json進(jìn)行encode和decode,需要的朋友可以參考下
    2014-11-11

最新評論

电白县| 弋阳县| 当涂县| 灵台县| 贡嘎县| 南宁市| 固镇县| 隆尧县| 嘉义市| 连江县| 亚东县| 土默特左旗| 青川县| 宝丰县| 聂荣县| 昆山市| 虞城县| 凤翔县| 虹口区| 大田县| 中牟县| 三台县| 和平县| 宜君县| 湛江市| 长沙市| 大英县| 宜阳县| 绥化市| 姚安县| 潞西市| 阳山县| 巴彦县| 四平市| 崇文区| 大港区| 云阳县| 青浦区| 拉孜县| 庆阳市| 临海市|