Lua中的元方法 newindex詳解

2021-07-22 14:51:18 字數 2818 閱讀 2208

好吧,我寫文章的進度已經趕不上看書的進度了,簡單的幾段文字就夠我嘮叨一篇文章了。

今天繼續來說說元方法,與__index有點相似的__newindex元方法。

1.查詢與更新

注意,【呼叫】這個詞,只是呼叫,而不是賦值。

如果,我們要對table中某個不存在的字段賦值呢?(小若:就,直接賦值啊!)

沒錯,我們直接就能賦值了,不會報錯的。

問題是,如果我想監控這個操作呢?如果有人想對table不存在的字段進行賦值的時候,我想進行一些額外的處理呢?

這時候就要用到__newindex。

大家要記住這句話:__index用於查詢,__newindex用於更新。

等會不要混亂了, 初次接觸的話,有可能會混亂。

2.看看普通的賦值情況

我們先來看看正常情況下的賦值,如**:

複製**

**如下:

local smartman =

local t1 = {};

local mt =

setmetatable(t1, mt);

t1.sayhello = function()

print("en");

end;

t1.sayhello();

複製**

**如下:

[lua-print] en

我們呼叫t1的sayhello欄位,t1並不存在這個字段(雖然可以通過__index的方式來找到smartman的sayhello欄位)。

但這不影響,給這個字段賦值,然後再呼叫t1.sayhello(),發現是成功的。

這和我們以往的做法一樣,對table做正常的賦值操作,不管table本身是否存在這個字段。

3.監控賦值

複製**

**如下:

local smartman =

local t1 = {};

local mt =

setmetatable(t1, mt);

t1.sayhello = function()

print("en");

end;

t1.sayhello();

留意mt元表,我們給它加了乙個__newindex。

執行**,輸出結果如下:

複製**

**如下:

[lua-print] sayhello欄位是不存在的,不要試圖給它賦值!

很顯然,sayhello欄位賦值失敗,因為給sayhello欄位賦值的時候,呼叫了

__newindex

元方法,代替了賦值操作。

(小若:為什麼?sayhello欄位不是存在的麼?為什麼會說不存在呢?)

這裡有乙個地方要注意的,t1中確實是不存在sayhello欄位的,它只是因為有元表存在,而元表裡的__index元方法的值是smartman這個table。

從而,可以在t1找不到sayhello欄位的時候,去smartman中尋找。

但,實際上,t1確實是不存在sayhello欄位的,不知道大家能繞明白不?

因此,當試圖給t1的sayhello欄位賦值時,lua判定sayhello欄位是不存在的,所以會去呼叫元表裡的__newindex元方法。

__newindex元方法被呼叫的時候會傳入3個引數:table本身、欄位名、想要賦予的值。

4.隔山打牛,通過給乙個table給另乙個table的字段賦值

和__index一樣,__newindex元方法也可以賦予乙個table值。

這種情況下就有點意思了,先看看**:

複製**

**如下:

local smartman =

local other =

local t1 = {};

local mt =

setmetatable(t1, mt);

print("other的名字,賦值前:" .. other.name);

t1.name = "小偷";

print("other的名字,賦值後:" .. other.name);

print("t1的名字:" .. t1.name);

這次的**和剛剛差不多,但是我們新加了乙個other的table,然後把other作為__newindex的值。

於是,當給t1的name欄位賦值時,就會發生一些奇怪的事情…

先來看看輸出結果:

複製**

**如下:

[lua-print] other的名字,賦值後:小偷

[lua-print] t1的名字:none

當給t1的name欄位賦值後,other的name欄位反而被賦值了,而t1的name欄位仍然沒有發生變化。

(實際上t1的name欄位還是不存在的,它只是通過__index找到了smartman的name欄位,這個就不嘮叨了。)

於是,我們給t1的name賦值的時候,實際上是給other的name賦值了。

好吧,可憐的other。

5.總結規則

這就是__newindex的規則:

a.如果__newindex是乙個函式,則在給table不存在的字段賦值時,會呼叫這個函式。

b.如果__newindex是乙個table,則在給table不存在的字段賦值時,會直接給__newindex的table賦值。

6.結束

好了,關於元表和元方法的基礎內容基本上告一段落了,接下來還有一篇關於元表和元方法的文章,也是一些比較零散的知識點。

之後,還會提到元表和元方法的,因為它們實在是太重要了。

lua中的元表和元方法

元表概念 lua中,物件導向是用元表這種機制來實現的 元表 matatable lua在建立新的table時不會建立元表,比如以下 就可以演示 local t print getmetatable t nil設定元表和獲取元表 getmetatable和setmetatable 使用getmetat...

lua 元表中 newindex元方法

元方法 index 對乙個表a的元素id賦值,如果在表a中元素id不存在,不對id賦值 會呼叫元表中 如果元表存在 的 newindex表,如果表a中存在id這個元素,則對賦值,不呼叫元表中 newindex local newindextable local metablea local tabl...

Lua中強大的元方法 index詳解

這篇文章主要介紹了lua中強大的元方法 index詳解,本文著重講解了使用 index元方法實現table的繼承,需要的朋友可以參考下 今天要來介紹比較好玩的內容 index元方法 1.我是備胎,記得回頭看看 咳咳,相信每一位女生都擁有或者不知不覺中擁有了一些備胎,啊,當然,又或許是成為過別人的備胎...