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 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
伞伞悦读1 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
C语言小火车1 天前
C/C++ 为什么需要编译器?
开发语言·c++
霍霍的袁1 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
孙启超1 天前
【AI开发之Rust】第 11 课:智能指针与内部可变性
开发语言·后端·rust
此生决int1 天前
深入理解C++系列(20)——C++11(下)
开发语言·c++
CoderYanger1 天前
A.每日一题:835. 图像重叠
java·开发语言·程序人生·leetcode·面试·职场和发展·学习方法
伞伞悦读1 天前
【第37期】Python JSON 与配置详解:序列化、反序列化、嵌套结构和配置文件
开发语言·python·json
CCCCCCCCharlie1 天前
Linux进程控制四大核心操作
linux·开发语言
Brilliantwxx1 天前
【STM32】 SPI Flash 驱动开发实战:阻塞模式驱动 W25Q64(含工程代码)
开发语言·stm32·单片机·嵌入式硬件