Lua—元表(Metatable)

原表解析

在 Lua table 中我们可以访问对应的 key 来得到 value 值,但是却无法对两个 table 进行操作(比如相加)。
因此 Lua 提供了元表(Metatable),允许我们改变 table 的行为,每个行为关联了对应的元方法。

  1. setmetatable(table,metatable): 对指定 table 设置元表(metatable),如果元表(metatable)中存在 __metatable 键值,setmetatable 会失败。
  2. getmetatable(table): 返回对象的元表(metatable)。

原表的定义

lua 复制代码
mytable={}      --普通表
mymetatable={}  --元表
setmetatable(mytable,mymetatable) --将mymetatable设置为mytable的原表

--可简写如下:
mytable=setmetatable({},{})

getmetatable(mytable) --会返回mytable的元表

原表的应用

1. 变量赋值

解析如下:

lua 复制代码
mymetatable={}
mytable=setmetatable({k1="v1"},{__newindex=mymetatable})

mytable.newkey="v2"
print(mytable.newkey,mymetatable.newkey)
--输出:nil   v2  :普通表中不含"newkey",会调用元方法

mytable.k1="newV"
print(mytable.k1,mymetatable.k1)
--输出:newV   nil :普通表中含有K1,会进行赋值,不再调用元方法

2.元方法调用函数

lua 复制代码
mytable=setmetatable({k1="v1"},{
    __newindex=function(mytable,k,v)--重写元方法
      rawset(mytable,k,"\""..v.."\"")--rawset绕过原表机制,直接向原表中插入新键值对
      end
    })
  mytable.k1="new v1";
  mytable.k2=3;--由于初始表中不k2,则会向元表中查询元方法
  print(mytable.k1,mytable.k2);
  
  --输出:v1   "3"

3.合并元表

lua 复制代码
function table_max(t)--获取原表最大键
  --用"#"或者table.getn时,若键不连续,只会获取第一段的最大值
  maxk=0;
  for k,v in pairs(t) do
    if type(k)=="number" and k>maxk then
      maxk=k
    end
  end
  return maxk
end

--实现两表合并
mytable=setmetatable({1,2,3},{__add=function(mytable,newtable)
      local mytable_maxk=table_max(mytable)
      for i=1,table_max(newtable) --遍历newtable
        table.insert(mytable,mytable_maxk+i,newtable[i])
        --将newtable中的数据插入到mytable中
      end
      return mytable
    end
  })

newtable={4,5,6}
mytable=mytable+newtable

for k,v in pairs(mytable) do
  print(k.."--"..v)
end
元方法 运算操作
__add "+"
__sub "-"
__mul "*"
__div "/"
__mod "%"
__unm "-"
__concat "..."
__eq "=="
__it "<"
__le "<="

注:"__"两个下划线,__sub对应二元减(两个参数);__unm对应一元减(只有一个参数)。

相关推荐
侃侃_天下1 天前
最终的信号类
开发语言·c++·算法
echoarts1 天前
Rayon Rust中的数据并行库入门教程
开发语言·其他·算法·rust
Aomnitrix1 天前
知识管理新范式——cpolar+Wiki.js打造企业级分布式知识库
开发语言·javascript·分布式
每天回答3个问题1 天前
UE5C++编译遇到MSB3073
开发语言·c++·ue5
伍哥的传说1 天前
Vite Plugin PWA – 零配置构建现代渐进式Web应用
开发语言·前端·javascript·web app·pwa·service worker·workbox
小莞尔1 天前
【51单片机】【protues仿真】 基于51单片机八路抢答器系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
我是菜鸟0713号1 天前
Qt 中 OPC UA 通讯实战
开发语言·qt
JCBP_1 天前
QT(4)
开发语言·汇编·c++·qt·算法
Brookty1 天前
【JavaEE】线程安全-内存可见性、指令全排序
java·开发语言·后端·java-ee·线程安全·内存可见性·指令重排序
百锦再1 天前
[特殊字符] Python在CentOS系统执行深度指南
开发语言·python·plotly·django·centos·virtualenv·pygame