好吧,我寫文章的進度已經(jīng)趕不上看書的進度了,簡單的幾段文字就夠我嘮叨一篇文章了。
今天繼續(xù)來說說元方法,與__index有點相似的__newindex元方法。
1.查詢與更新
上一篇文章我們介紹了__index元方法,總結來說,__index元方法是用于處理調用table中不存在的字段。
注意,【調用】這個詞,只是調用,而不是賦值。
如果,我們要對table中某個不存在的字段賦值呢?(小若:就,直接賦值啊?。?/p>
沒錯,我們直接就能賦值了,不會報錯的。
問題是,如果我想監(jiān)控這個操作呢?如果有人想對table不存在的字段進行賦值的時候,我想進行一些額外的處理呢?
這時候就要用到__newindex。
大家要記住這句話:__index用于查詢,__newindex用于更新。
等會不要混亂了, 初次接觸的話,有可能會混亂。
2.看看普通的賦值情況
我們先來看看正常情況下的賦值,如代碼:
這是上一篇用過的例子,一個模仿繼承結構的例子。
來分析一下,mt作為t1的元表,設置__index為smartMan。
于是,當我們調用t1中不存在的字段時,就會自動去smartMan中查找。
比如我們調用了t1.sayHello(),自然能找到對應的函數(shù)。
先來看看輸出結果:
但這不影響,給這個字段賦值,然后再調用t1.sayHello(),發(fā)現(xiàn)是成功的。
這和我們以往的做法一樣,對table做正常的賦值操作,不管table本身是否存在這個字段。
3.監(jiān)控賦值
好了,普通情況我們已經(jīng)試過了,如果我們想監(jiān)控table的賦值操作呢?
對于不存在的字段,我們不需要被賦值呢?想要制作一個只讀的table呢?
如果你有這些想法,那么歡迎撥打屏幕下方的號碼,前10位打進的還贈送價值..(小若:停?。?br />
那么,如果你有這些想法,請看看下面的代碼:
留意mt元表,我們給它加了一個__newindex。
運行代碼,輸出結果如下:
(小若:為什么?sayHello字段不是存在的么?為什么會說不存在呢?)
這里有一個地方要注意的,t1中確實是不存在sayHello字段的,它只是因為有元表存在,而元表里的__index元方法的值是smartMan這個table。
從而,可以在t1找不到sayHello字段的時候,去smartMan中尋找。
但,實際上,t1確實是不存在sayHello字段的,不知道大家能繞明白不?
因此,當試圖給t1的sayHello字段賦值時,Lua判定sayHello字段是不存在的,所以會去調用元表里的__newindex元方法。
__newindex元方法被調用的時候會傳入3個參數(shù):table本身、字段名、想要賦予的值。
4.隔山打牛,通過給一個table給另一個table的字段賦值
和__index一樣,__newindex元方法也可以賦予一個table值。
這種情況下就有點意思了,先看看代碼:
這次的代碼和剛剛差不多,但是我們新加了一個other的table,然后把other作為__newindex的值。
于是,當給t1的name字段賦值時,就會發(fā)生一些奇怪的事情…
先來看看輸出結果:
(實際上t1的name字段還是不存在的,它只是通過__index找到了smartMan的name字段,這個就不嘮叨了。)
于是,我們給t1的name賦值的時候,實際上是給other的name賦值了。
好吧,可憐的other。
5.總結規(guī)則
這就是__newindex的規(guī)則:
a.如果__newindex是一個函數(shù),則在給table不存在的字段賦值時,會調用這個函數(shù)。
b.如果__newindex是一個table,則在給table不存在的字段賦值時,會直接給__newindex的table賦值。
6.結束
好了,關于元表和元方法的基礎內容基本上告一段落了,接下來還有一篇關于元表和元方法的文章,也是一些比較零散的知識點。
之后,還會提到元表和元方法的,因為它們實在是太重要了。