• 关于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
  • 相关阅读:
    Linux概念与体系阅读笔记
    iOS缓存
    iOS开发笔记系列-基础3(多态、动态类型和动态绑定)
    在进入新版本 的时候,进行推送引导
    手机号验证
    通过UIView对象获取该对象所属的UIViewController(转)
    支付宝和微信支付的各种填坑
    IOS开发简单登录LoginViewController、注册RegisterViewController、UcenterViewController功能实现方法
    iOS 注册登录页面
    多媒体元素的使用
  • 原文地址:https://www.cnblogs.com/wang-jin-fu/p/13511870.html
Copyright © 2020-2023  润新知