• 关于lua的__index和元表的关系


    一直比较疑惑,当访问表a中不存在的元素x时,a.__index,mt,mt.__index是怎么查询的?

    先上结论:当访问table a中不存在的元素时,既不会查询a的__index,也不会查询a元表的其他元素,只会查询a元表的__index。

    Lua 查找一个表元素时的规则,其实就是如下3个步骤

    1.在表中查找,如果找到,返回该元素,找不到则继续

    2.判断该表是否有元表,如果没有元表,返回nil,有元素则继续。

    3.判断元表有没有__index,如果__index为nil ,则返回nil;否则

      如果__index是一个函数,则返回该函数的返回值,参数为表本身和查找的key。

      如果__index是一个表,则重复1、2、3。

      如果__index不是函数和表,则报错attempt to index a xxx value

    a = {}
    print(a.x) -- nil
    
    a.__index = 1
    print(a.x) --nil,不访问自身的__index
    
    a.__index = {x = 2}
    print(a.x) --nil,不访问自身的__index
    
    mt = {x = 3}
    setmetatable(a, mt)
    print(a.x) -- nil,不访问元表的对象
    
    mt = {x = 4}
    mt.__index = 5
    setmetatable(a, mt)
    --print(a.x) --error:attempt to index a number value,如果元表的__index不是方法,当做table处理,所以这边报错了
    
    mt.__index = {x = 7}
    setmetatable(a, mt)
    print(a.x) --7,成功访问到元表的__index对应的表{x = 7}

    那么lua一般的继承实现中的代码就好理解了:

    1.setmetatable(cls, {__index = super})为什么不是setmetatable(cls, super),因为前者访问的是super,后者访问的是super.__index.

    2.cls.__index = cls,因为最终返回的是instance,而instance = setmetatable({}, cls)。如果不加上这句,反问instance中不存在的元素时,只会在cls.__index = nil中查找,永远也查不到父类。

    local cls
    if
    super then cls = {} setmetatable(cls, {__index = super}) cls.super = super else cls = {ctor = function() end} end cls.__cname = classname cls.__ctype = 2 -- lua cls.__index = cls function cls.ToString(self) return self.__cname end function cls.new(...) local instance = setmetatable({}, cls) instance.class = cls instance:ctor(...) return instance end
    return cls
  • 相关阅读:
    洛谷 P1781 宇宙总统
    洛谷 P2524 Uim的情人节礼物·其之弐(康拓展开)
    洛谷 P1123 取数游戏
    洛谷 P4147 玉蟾宫 & P1169 [ZJOI2007]棋盘制作(求最大子矩阵)
    洛谷 P1387 最大正方形 & P2701 [USACO5.3]巨大的牛棚Big Barn (求最大子正方形)
    洛谷 P1464 Function
    洛谷 P1217 [USACO1.5]回文质数 Prime Palindromes
    洛谷 P1160 队列安排
    洛谷 P1451 求细胞数量
    洛谷 P1914 小书童——密码
  • 原文地址:https://www.cnblogs.com/wang-jin-fu/p/13511870.html
Copyright © 2020-2023  润新知