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

相关推荐
lkbhua莱克瓦2412 小时前
Java基础——集合进阶3
java·开发语言·笔记
多喝开水少熬夜12 小时前
Trie树相关算法题java实现
java·开发语言·算法
QT 小鲜肉12 小时前
【QT/C++】Qt定时器QTimer类的实现方法详解(超详细)
开发语言·数据库·c++·笔记·qt·学习
lsx20240612 小时前
MySQL WHERE 子句详解
开发语言
Tony Bai12 小时前
【Go模块构建与依赖管理】09 企业级实践:私有仓库与私有 Proxy
开发语言·后端·golang
Lucky小小吴13 小时前
开源项目5——Go版本快速管理工具
开发语言·golang·开源
Mr.Jessy13 小时前
Web APIs 学习第五天:日期对象与DOM节点
开发语言·前端·javascript·学习·html
杨福瑞13 小时前
数据结构:单链表(2)
c语言·开发语言·数据结构
进化中的码农13 小时前
Go中的泛型编程和reflect(反射)
开发语言·笔记·golang
音符犹如代码14 小时前
Java并发List实战:CopyOnWriteArrayList原理与ArrayList常见面试题
java·开发语言·面试·list