Lua中元表/元メソッド_index詳細

2459 ワード

Lua元表の心得を理解する:
1つのtableに対して値を取る操作を行うと想像してみましょうが、tableにはこの値がありませんか?例:
 local t = {
         name = "hehe",
     }
     print(t.money);

出力結果はもちろんnil
tはnameというフィールドにのみ使用されますが、moneyフィールドにアクセスすると、自然にnilに戻ります.
しかし、もし私たちがそうしたくないなら?存在しないフィールドにアクセスするときに、いくつかのカスタム操作を行いたいですか?大丈夫、Luaは私たちを満たして、それは、indexメタメソッド.
加算を使用すると、__が検索されます.addメタメソッドでは、tableが存在しないフィールドを呼び出すと__が呼び出されます.indexメタメソッド、これは同じルールです.コードを見てみましょう.
 local t = {
         name = "hehe",
     }
    
     local mt = {
         __index = function(table, key)
             print("             ,     ,      :" .. key);
         end
     }
     setmetatable(t,mt);
    
     print(t.money);

tableにカスタムメタテーブル、メタテーブルの__を設定しましたindexメタ法は我々の関数を用いた.実行結果は次のとおりです.

    [LUA-print]              ,     ,      :money 
   
[LUA-print] nil

存在しないmoneyフィールドが呼び出されるとtableメタテーブルの__が呼び出されますindexメタメソッドで、tableとフィールド名の2つのパラメータが渡されます.
そこで、この関数でカスタム操作をたくさんすることができます.
2.継承の実現方法
まだ継承を説明する時ではありませんが、まず少し味わってみましょう.
tableに存在しないフィールドが呼び出されると、tableメタテーブルの__が呼び出されます.indexメタメソッド、これはさっき言ったばかりです.
でも、これならindexメタメソッドがtableであれば、このtableでフィールドを検索して呼び出します.
そういえば、ちょっと混乱していて、コードを見ればわかります.
 local t = {
         name = "hehe",
     }
    
     local mt = {
         __index = {
             money = "900,0000",
         }
     }
     setmetatable(t,mt);
    
     print(t.money);

注意_index、moneyオブジェクトがあるtableを割り当てました.
では、tの存在しないフィールドが呼び出されると、__が検索されるindexのtableは、このフィールドが見つかったら呼び出します.
これは微妙で、完全に予備胎の潜在質で、tの中で見つからない時だけ、この「予備胎」を思い出します.出力結果は次のとおりです.

    [LUA-print] 900,0000 
  

3.継承を試みる
さっきの例では「継承」の概念を体得できませんでしたが、もう一つの例を見てみましょう.
     local smartMan = {
         name = "none",
         age = 25,
         money = 9000000,
        
         sayHello = function()
             print("   ,      。");
         end
     }
    
     local t1 = {};
     local t2 = {}
    
     local mt = {__index = smartMan}
    
     setmetatable(t1, mt);
     setmetatable(t2, mt);
    
     print(t1.money);
     t2.sayHello();

出力結果は
[LUA-print] 900,0000
[LUA-print]こんにちは、私は賢い豪です.
「ベースクラス」としてsmartManというtableを定義した.
次に2つのtable,t 1,t 2を新規作成し,smartManをメタテーブルの__とする.indexメタメソッド.
すると、t 1,t 2のmoneyまたはsayHelloフィールドが呼び出されると、実際にsmartManのフィールドが見つかる.継承のように見えるのではないでしょうか.