理解Lua語言中的__index,__newindex,rawget和rawset

來源:互聯網
上載者:User

在談及Lua中的__index,__newindex,rawget和rawset前,需要理解Lua中的元表這個概念。

零、元表的概念

對Lua中元表的解釋: 元表可以改變表的行為模式。

這裡舉個例子:

Window = {}Window.prototype = {x = 0 ,y = 0 ,width = 100 ,height = 100,}Window.mt = {}function Window.new(o)setmetatable(o ,Window.mt)return oendWindow.mt.__index = Window.prototypeWindow.mt.__newindex = function (table ,key ,value)if key == "wangbin" thenrawset(table ,"wangbin" ,"yes,i am")endendw = Window.new{x = 10 ,y = 20}w.wangbin = "55"print(w.wangbin)

然後,我們可以看到列印資訊是:yes,i am

原本賦值的地方是w.wangbin = "55",但是結果卻是 yes,i am。

這裡就改變了元表的行為模式。

一、__index的理解

__index是:當我們訪問一個表中的元素不存在時,則會觸發去尋找__index元方法,如果不存在,則返回nil,如果存在,則返回結果。

Window = {}Window.prototype = {x = 0 ,y = 0 ,width = 100 ,height = 100,}Window.mt = {}function Window.new(o)setmetatable(o ,Window.mt)return oendWindow.mt.__index = function (t ,key)-- bodyreturn 1000endw = Window.new{x = 10 ,y = 20}print(w.wangbin)

列印結果是:1000。可以看出,我們在new的時候,w這個表裡其實沒有wangbin這個元素的,我們重寫了元表中的__index,使其返回1000,意思是:如果你要尋找的元素,該表中沒有,那麼預設返回1000。

二、__newindex的理解

__newindex:當給你的表中不存在的值進行賦值時,lua解譯器則會尋找__newindex元方法,發現存在該方法,則執行該方法進行賦值,注意,是使用

Window.mt = {}function Window.new(o)setmetatable(o ,Window.mt)return oendWindow.mt.__index = function (t ,key)return 1000endWindow.mt.__newindex = function (table ,key ,value)if key == "wangbin" thenrawset(table ,"wangbin" ,"yes,i am")endendw = Window.new{x = 10 ,y = 20}w.wangbin = "55"print(w.wangbin)
ok,這裡的列印結果是:yes,i am。w這個表裡本來沒有wangbin這個元素的,我們重寫了元表中__newindex,並在__newindex方法中重新進行賦值操作,然後,我們對這個本不存在的原色w.wangbin進行賦值時,執行__newindex方法的賦值操作,最後,列印結果便是:yes,i am

三、rawget和rawset的理解

是為了繞過__index而出現的,直接點,就是讓__index方法的重寫無效。(我這裡用到"重寫"二字,可能不太對,希望能得到糾正)

Window = {}Window.prototype = {x = 0 ,y = 0 ,width = 100 ,height = 100,}Window.mt = {}function Window.new(o)setmetatable(o ,Window.mt)return oendWindow.mt.__index = function (t ,key)return 1000endWindow.mt.__newindex = function (table ,key ,value)if key == "wangbin" thenrawset(table ,"wangbin" ,"yes,i am")endendw = Window.new{x = 10 ,y = 20}print(rawget(w ,w.wangbin))
列印結果是:nil。這裡的元表中__index函數就不再起作用了。

但是rawset呢,起什麼作用呢?我們再來運行一段代碼。

Window = {}Window.prototype = {x = 0 ,y = 0 ,width = 100 ,height = 100,}Window.mt = {}function Window.new(o)setmetatable(o ,Window.mt)return oendWindow.mt.__index = function (t ,key)return 1000endWindow.mt.__newindex = function (table ,key ,value)table.key = "yes,i am"endw = Window.new{x = 10 ,y = 20}w.wangbin = "55"
然後我們的程式就stack overflow了。可見,程式陷入了死迴圈。因為w.wangbin這個元素本來就不存在表中,然後這裡不斷執行進入__newindex,陷入了死迴圈。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.