美文网首页
set/getmetatable与debug.set/getme

set/getmetatable与debug.set/getme

作者: 凉夜lrs | 来源:发表于2021-02-01 10:28 被阅读0次
    --set/getmetatable
    
    {"setmetatable", luaB_setmetatable},
    {"getmetatable", luaB_getmetatable},
    
    static int luaB_setmetatable (lua_State *L) {
      int t = lua_type(L, 2);
      luaL_checktype(L, 1, LUA_TTABLE);
      luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
                        "nil or table expected");
      if (luaL_getmetafield(L, 1, "__metatable"))
        luaL_error(L, "cannot change a protected metatable");
      lua_settop(L, 2);
      lua_setmetatable(L, 1);
      return 1;
    }
    
    static int luaB_getmetatable (lua_State *L) {
      luaL_checkany(L, 1);
      if (!lua_getmetatable(L, 1)) {
        lua_pushnil(L);
        return 1;  /* no metatable */
      }
      luaL_getmetafield(L, 1, "__metatable");
      return 1;  /* returns either __metatable field (if present) or metatable */
    }
    
    --debug.set/getmetatable
    
    {"setmetatable", db_setmetatable},
    {"getmetatable", db_getmetatable},
    
    static int db_setmetatable (lua_State *L) {
      int t = lua_type(L, 2);
      luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
                        "nil or table expected");
      lua_settop(L, 2);
      lua_pushboolean(L, lua_setmetatable(L, 1));
      return 1;
    }
    
    static int db_getmetatable (lua_State *L) {
      luaL_checkany(L, 1);
      if (!lua_getmetatable(L, 1)) {
        lua_pushnil(L);  /* no metatable */
      }
      return 1;
    }
    

    可以看到,两者不同的地方在于,setmetatable 有检测 __metatable 键值,如果存在,setmetatable 会失败。而 getmetatable 会优先返回 __metatable 键值的内容,不存在再返回 metatable。举例说明:

    local a = {}
    setmetatable(a, {__metatable = "lock"})
    print(type(getmetatable(a)), getmetatable(a))
    print(type(debug.getmetatable(a)), debug.getmetatable(a))
    debug.setmetatable(a, {__metatable = "lock2"})
    setmetatable(a, {__metatable = "lock2"})
    
    image.png

    相关文章

      网友评论

          本文标题:set/getmetatable与debug.set/getme

          本文链接:https://www.haomeiwen.com/subject/lhljtltx.html