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对应一元减(只有一个参数)。

相关推荐
Susea&7 分钟前
趣味编程:四叶草
c语言·开发语言·c++·技术美术
大道随心37 分钟前
【wpf】10 C#树形控件高效实现:递归构建与路径查找优化详解
开发语言·c#·wpf
香蕉可乐荷包蛋44 分钟前
Python学习之路(玖)-图像识别的实现
开发语言·python·学习
航Hang*1 小时前
C PRIMER PLUS——第6-2节:二维数组与多维数组
c语言·开发语言·经验分享·程序人生·算法·学习方法·visual studio
易只轻松熊1 小时前
C++(1):整数常量
开发语言·c++
努力的搬砖人.2 小时前
Java 线程池原理
java·开发语言
Dovis(誓平步青云)2 小时前
精讲C++四大核心特性:内联函数加速原理、auto智能推导、范围for循环与空指针进阶
c语言·开发语言·c++·笔记·算法·学习方法
passionSnail2 小时前
《用MATLAB玩转游戏开发》Flappy Bird:小鸟飞行大战MATLAB趣味实现
开发语言·matlab
jz_ddk2 小时前
[学习]RTKLib详解:convkml.c、convrnx.c与geoid.c
c语言·开发语言·学习
stevenzqzq2 小时前
kotlin flow防抖
开发语言·kotlin·flow