zoukankan      html  css  js  c++  java
  • 关于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
  • 相关阅读:
    Vue.js
    docker搭建pxc
    mkvirtualenv管理python版本
    gitlab
    centos7安装kvm及kvm管理
    centos7安装docker
    【从NIO到Netty】8.零拷贝案例2-网络传输
    【从NIO到Netty】7.零拷贝案例1-复制文件
    【从NIO到Netty】6.零拷贝介绍
    【从NIO到Netty】5.NIO EchoServer
  • 原文地址:https://www.cnblogs.com/wang-jin-fu/p/13511870.html
Copyright © 2011-2022 走看看