• Metatable让我从心认知了Lua(相知篇)


       自从在公司和Lua第一次相遇之后,我的IT生涯从此也开启了另一个新篇。。。

    起初并没有和Lua产生相遇时的那种电石火花般的怦然心动。。。但。。。

    说实话虽然我的心没有因此触动但至少也不排斥。。。因为公司的需要,我就

    必须去爱上她,所以大家都懂得。。。我们开始了正式的"交往"咯^_^ ^_^ ^_^

      在与Lua"交往"的这段时光里,你会发现自己已经渐渐的被Lua所吸引。。。

    她虽然没有令你一见钟情的"容貌",但却有着你喜欢的那种日久生情的"气质"。。。

      废话就不多说了、、、咱直接进入主题吧。。。细说Metatable(元表)的那点事。。。

    如果你想对lua中table的结构进行变化。。。那么就用lua的元表就来帮你实现。。。请看下面详解。。。

    ==>这次的博文新增了导航栏,,,方便博友们上下滚动网页来回切换视角、也别忽视了右侧的浮动目录。。。

    一、 __index元方法

    __index元方法:用于查看表中元素是否存在,如果不存在返回结果为nil;如果存在,则由__index返回结果

      存在__index元方法:

    myTable = setmetatable({key1 = "lua", key3 = "java"}, {
        __index = function(myTable, key)
            if key == "key2" then
              return "key2 is nil"
          else
              return myTable[key]
          end
        end
    })

      程序运行输出:

    ---------- 新建程序 ----------
    lua    key2 is nil    java
    
    输出完成 (耗时 0 秒) - 正常终止

      不存在__index元方法:

    myTable = {key1 = "lua", key3 = "java"}
    
    print(myTable.key1, myTable.key2, myTable.key3)

      程序运行输出:

    ---------- 新建程序 ----------
    lua    nil    java
    
    输出完成 (耗时 0 秒) - 正常终止

    二、__newindex元方法

    __newindex元方法:用来对表进行更新。给一个表的缺少的索引赋值时,解释器就会查找是否存在__newindex元方法,

              如果存在则调用这个函数而不进行赋值操作;不存在则进行赋值操作。(只针对表中不存在的索引有效)

      存在__newindex元方法:

    myTable = {key1 = "lua", key3 = "java"}
    
    setmetatable(myTable, {
        __newindex = function(myTable, key, value)
          print(key .. " is not exists in myTable " .. value)
        end
    })
    
    myTable.key1 = "hello"
    myTable.key2 = "world"    --给key2赋值会执行__newindex函数
    
    print(myTable.key1, myTable.key2)

      程序运行输出:

    ---------- 新建程序 ----------
    key2 is not exists in myTable world
    hello    nil
    
    输出完成 (耗时 0 秒) - 正常终止

      解释说明:  在给myTable表的key1索引赋值时,因为key1索引是myTable中已经存在的索引,

           所以只进行赋值而不调用__newindex元方法;

             在给myTable表的key2索引赋值时,因为key2索引在myTable表中不存在,解释器就会查找

           是否存在__newindex元方法,又由于存在__newindex元方法,所以调用了__newindex元方法

           而不对key2索引进行赋值;若不存在__newindex方法,则对新索引进行赋值操作。 

       不存在__newindex元方法:

    myTable = {key1 = "lua", key3 = "java"}
    
    myTable.key1 = "hello"
    myTable.key2 = "world"    
    
    print(myTable.key1, myTable.key2)

      程序运行输出:

    ---------- 新建程序 ----------
    hello    world
    
    输出完成 (耗时 0 秒) - 正常终止

    三、__add元方法

     __add元方法:用于操作表与表之间的关联事件。当两张表之间用到字符'+'时,解释器就会去查找是否存在__add元方法,

            若存在__add元方法,则调用__add元方法,否则程序执行报错。(对应的运算符:'+')

       存在__add元方法:

    myTable = {10, 20, 30}
    newTable = {20, 30, 40}
    
    setmetatable(myTable, {
        __add = function(myTable, newTable)
          print("add")    --此处用来处理相关事件,可遍历两个对其中的元素进行累加求和并返回
          return "already add"
        end
    })
    
    print(myTable + newTable)

      程序运行输出:

    ---------- 新建程序 ----------
    add
    already add
    
    输出完成 (耗时 0 秒) - 正常终止

    四、__sub元方法

     __sub元方法:用法类似于__add元方法。(对应的运算符:'-')

    myTable = {10, 20, 30}
    newTable = {20, 30, 40}
    
    setmetatable(myTable, {  
        __sub = function(myTable, newTable)  --__sub可替换__mul/__div/__mod/__unm/__concat/__eq/__lt/__le
          print("subtract")    --处理相关事件
          return "already subtract"
        end
    })
    
    print(myTable - newTable)  --此处要替换为相应的对应运算符

      程序运行输出:

    ---------- 新建程序 ----------
    subtract
    already subtract
    
    输出完成 (耗时 0 秒) - 正常终止

     类似于__add和__sub元方法的还有:

      __mul元方法:对应运算符'*'

      __div元方法:对应运算符'/'

      __mod元方法:对应运算符'%'

      __pow元方法:对应运算符'^'

      __unm元方法:对应运算符'-',此处的运算符不是减号,是代表负数

      __concat元方法:对应运算符'..'

      __eq元方法:对应运算符'=='

      __lt元方法:对应运算符'<'

      __le元方法:对应运算符'<='

    最后再拿__unm元方法举例:

    myTable = {10, 20, 30}
    
    setmetatable(myTable, {
        __unm = function(myTable)
          print("nagative")    --处理相关事件
          return "already nagative"
        end
    })
    
    print(-myTable)

      程序运行输出:

    ---------- 新建程序 ----------
    nagative
    already nagative
    
    输出完成 (耗时 0 秒) - 正常终止

    五、__call元方法

     __call元方法:用于表变量调用一个参数时调用__call元方法。

    myTable = {10, 20, 30}
    num = 100
    
    setmetatable(myTable, {
        __call = function(myTable, param)    --此处的param可替换其他类型的变量
          print("call " .. param)    --处理相关事件
          return "already call"
        end
    })
    
    print(myTable(num))  --myTable调用num变量

      程序运行输出:

    ---------- 新建程序 ----------
    call 100
    already call
    
    输出完成 (耗时 0 秒) - 正常终止

    六、__tostring元方法

     __tostring元方法:用于修改表的输出行为。【类似于JAVA中类中重写了toString()方法,用于修改对象的输出行为

    --写法一
    myTable = {10, 20, 30}
    
    setmetatable(myTable, {
        __tostring = function(myTable)    --注意__tostring是两个_开头
          local sum = 0
          for _,v in pairs(myTable) do  --注意此处的_字符也表示变量,可用字母k或其他字母替代
              sum = sum + v
          end
          return ("表元素之和=" .. sum)
        end
    })
    
    print(myTable)
    

    --写法二 myTable = {10, 20, 30} mt = {} mt.__tostring = function(myTable) local sum = 0 for _,v in pairs(myTable) do   sum = sum + v end return ("表元素之和=" .. sum) end setmetatable(myTable, mt) print(myTable)

      循环遍历部分也可修改为:

    for index = 1,#myTable do
        sum = sum + myTable[index]
    end

      程序运行输出:

    ---------- 新建程序 ----------
    表元素之和=60
    
    输出完成 (耗时 0 秒) - 正常终止

       

      明天就要去出差了、、、在这之前。。把我和Lua的相知篇赶出来和大家分享。。。

    希望多少能够给大家带来一点帮助。。。

      如果博友们看出了我在认知Lua的过程中,,,对Lua有误解。。。说出来、、、

    我们一起探讨探!!!  *^_^*

      如果觉得此博文写的还行、看着还不错的博友们。。。移动起你们的鼠标。。。轻轻一点推荐

    把祝福传给我们。。。让知识传递下去。。。 *^_^* *^_^* *^_^*

      有想关注和阅读我最新博文的博友们。。。就关注走一波咯。。。

       

           喜欢和爱是有差别的。。。

         喜欢是让自己高兴,,,爱却是让对方幸福。。。

        喜欢是一种占有,,,爱更多的是一种付出,一种责任。。。

      想要看起来毫不费力,,,在这之前你就必须全力以赴。。。

  • 相关阅读:
    《linux 内核全然剖析》 笔记 CODE_SPACE 宏定义分析
    Item 8:析构函数不要抛出异常 Effective C++笔记
    Eclipse经常使用快捷键
    多人即时战斗游戏服务端系列[2]--90坦克Online游戏对象介绍以及渲染机制
    STM8S awu及看门狗IWDG WWDG应用(转)
    使用STM8SF103 ADC采样电压(转)
    BHS-STM32工具系列
    STM32 FLASH模拟EEPROM 使用和优化(转)
    STM32+NRF24L01无线(转)
    像51一样操作STM32的IO(转)
  • 原文地址:https://www.cnblogs.com/JimLy-BUG/p/5364281.html
Copyright © 2020-2023  润新知