Lua 提供了元表(Metatable),允许我们改变 table 的行为,每个行为关联了对应的元方法。

两个函数来处理元表:
setmetatable(table,metatable):对指定table设置元表(metatable),返回table。如果元表(metatable)中存在 __metatable 键值,setmetatable 会失败。
getmetatable(table): 返回对象的元表(metatable)。

设置元表:

mytable = {}                          -- 普通表
mymetatable = {}                      -- 元表
setmetatable(mytable,mymetatable)     -- 把 mymetatable 设为 mytable 的元表--相当于 mytable = setmetatable({},{})

元方法

  • __index 元方法

__index元方法用来对表进行访问 。访问table的时候,如果没有这个key,那么会查找metatable中__index的key。

  1. 如果__index指向一个表,Lua会在表中查找相应的key。
mytable = setmetatable({key = 1},{__index = {key2 = 2}})
print(mytable.key)   --1
print(mytable.key2)  --2
  1. 如果__index指向一个函数的话,Lua就会调用那个函数,table和key会作为参数传递给函数。
local  function mymetatable(table,key)return "访问了table中不存在的key:"..key
end
mytable = setmetatable({key1 = "value1"}, {__index = mymetatable
})
print(mytable.key1)
print(mytable.key2)
  • __newindex 元方法

__newindex 元方法用来对表更新。更新table的时候,如果没有这个key,那么会查找metatable中__newindex元方法,如果存在则调用这个元方法而不对table进行操作。

  1. 如果__newindex指向一个表,Lua会在表中更新相应的key。
mymetatable = {}
mytable = setmetatable({key1 = "key1"}, { __newindex = mymetatable })
print(mytable.key1)--key1
mytable.newkey = "newkey"
print(mytable.newkey) -- nil
print(mymetatable.newkey) -- newkey
--mytable 中没有newkey,调用元表中的__newindex,对mymetatable更新
mytable.key1 = "newkey_1"
print(mytable.key1) --newkey_1
print(mymetatable.key1) --nil
--mytable 中有key1,直接更新mytable
  1. 如果__newindex指向一个函数的话,Lua就会调用那个函数,table,key,value会作为参数传递给函数。
    可以使用rawset函数更新表的数据:
mytable = setmetatable({key1 = "value1"}, {__newindex = function(mytable, key, value)rawset(mytable, key, "\""..value.."\"")end
})mytable.key1 = "new value"
mytable.key2 = 4print(mytable.key1,mytable.key2)

创建只读table,防止table被别人修改

function ReadOnly(t)local proxy = {}  --定义一个空表,访问任何索引都是不存在的,所以会调用__index 和__newindexlocal mt = {__index = t, ---__index 可以是函数,也可以是table,是table的话,调用直接返回table的索引值__newindex = function(t,k,v)error("attempt to update a read-only table",2)end}setmetatable(proxy,mt)return proxy
enddays = ReadOnly{"Sunday","Monday","Tuesday","Wednessday","Thursday","Friday","Saturday"}
print(days[1])
days[2] = "hello"                      --这一行就非法访问了
  • 表的运算操作符元方法

运算操作符指向一个函数,当使用运算符时,lua会调用对应的元方法,并将运算符两边的表当作参数传入元方法。
__add 对应的运算符 ‘+’.
__sub 对应的运算符 ‘-’.
__mul 对应的运算符 ‘*’.
__div 对应的运算符 ‘/’.
__mod 对应的运算符 ‘%’.
__unm 对应的运算符 ‘-’.
__concat 对应的运算符 ‘…’.
__eq 对应的运算符 ‘==’.
__lt 对应的运算符 ‘<’.
__le 对应的运算符 ‘<=’.

local function addFunc(a, b)for i = 1, #b dotable.insert(a, #a+1,b[i])endreturn a
end
-- 两表相加操作
mytable = setmetatable({ 2, 3 }, {__add = addFunc
})secondtable = {5,6}mytable = mytable + secondtablefor k,v in ipairs(mytable) do
print(k,v)
end
  • __call 元方法

当table调用一个值时会调用__call 元方法,并将table和传入的参数作为
__call 的参数。参数可以是表,值,字符串

mytable = setmetatable({10}, {__call = function(mytable, args)sum = 0for i = 1, #(mytable) dosum = sum + mytable[i]endsum = sum+ argsreturn sumend
})
print(mytable(1))                     -- 11
  • __tostring 元方法

__tostring 元方法用于修改表的格式化输出字符串。

local mytable = { 10, 20, 30 }
print(mytable)                    --table: 0xb42650
mytable = setmetatable(mytable, {__tostring = function(mytable)local str = "{"for k, v in pairs(mytable) dostr = str.. v ..","endreturn  str.."}"end
})
print(mytable)                      --{10,20,30,}

【Lua笔记】、Lua元表相关推荐

  1. Lua笔记-关于lua table的C API

    //Lua笔记-关于lua table的C API //转载请注明来自yuliying的CSDN博客. //Lua版本5.2 /*相关API: ====lua_createtable 原型: void ...

  2. 游戏开发学习笔记——lua脚本语言——安装、汉化与小测试(解决lua运行代码乱码问题)

    游戏开发学习笔记--lua脚本语言--安装.汉化与小测试 FOR THE SIGMA FOR THE GTINDER FOR THE ROBOMASTER 简介: Lua 是一种轻量小巧的脚本语言,用 ...

  3. lua笔记之local

    lua笔记之local 最近使用lua语言遇到一个小问题,这里要记录一下 lua 中使用 local 的变量,例如: function testLocal()print(a, b)a = 10086l ...

  4. 脚本语言lua笔记(5)c++调用lua

    首先搭建环境,使用vs2010的c++开发工具,lua源码包,可以去官方下载最新源码包,我采用的是lua-5.1.5的版本.好了,开始配环境. 第一步: 下载源码包后,解压lua-5.1.5源码包到硬 ...

  5. lua笔记之userdata

    1.一直使用框架里封装好的c库,想着自己一点一点的写些例子,学习下,以后需要c库,可以自己写了. 下边是一个简单的userdata的例子--数组操作. newarray.c #include &quo ...

  6. Redis学习笔记 - Lua脚本(2) - Lua脚本的实现

    参考:<<Redis设计与实现>> 注:这本书是基于Redis3.0版本写的,和后面的版本有点差异 Redis中Lua脚本相关命令介绍以及简单使用,参考博客:https://b ...

  7. 【Lua】Lua基础语法

    1 Lua 简介 Lua 是一个小巧的脚本语言,用标准C语言编写而成,由巴西里约热内卢天主教大学的 Roberto Ierusalimschy.Waldemar Celes 和 Luiz Henriq ...

  8. lua学习01:c调用lua、lua调用c、lua的协程、lua的常见API、lua读取配置文件总结

    文章目录 1.c通过虚拟机和虚拟栈调用lua test-vm.c test-vm.lua 打印效果 2.lua通过虚拟机和虚拟栈调用c lua-tbl.c test-tbl.lua 3.lua的协程 ...

  9. 【Lua】Lua知识点汇总

    Lua知识点汇总 一.理解Lua的执行 二.Lua编译器 2.1 词法分析器 2.2 抽象语法树 2.3 语法分析 2.4 代码生成 三.Lua解析器 3.1 luac命令 3.2 二进制chunk格 ...

最新文章

  1. 8188无线网卡驱动linux,rtl8188eu linux驱动
  2. python【数据结构与算法】多字段条件排序
  3. 【Python】密码生成器
  4. fenby C语言 P11
  5. 代码评审 16.7.1
  6. 【基础数据库】经济行业分类
  7. 监控提示服务器状态变更,服务器故障排除与状态监控
  8. 机器人周志_机器人教学的意义
  9. 实验室虚拟仿真建设之技术选型剖析
  10. 宋体和英文字号与matlab中对照,CSS字体中英文名称对照表:如宋体对应SimSun
  11. 插值器和估值器概述与使用
  12. html参考文献英文文献,写英文paper的参考文献格式How To Cite References - Chicago Style...
  13. 安卓中的布局优化之clude、merge、ViewStub
  14. 网友评价 iPhone 8:大爱玻璃后壳、True Tone 屏幕
  15. oeasy 教您玩转 linux 010400 总结 summary
  16. M56 智慧井盖的技术应用
  17. EndeavourOS安装配置全攻略!
  18. bilibiliC++概念遍览
  19. 懒惰学习_为了懒惰!
  20. Qt之QIODevice笔记

热门文章

  1. 1053:最大数输出
  2. 计蒜客 王子救公主 dfs
  3. android8沉浸式状态栏,Android 沉浸式状态栏
  4. 吕泉高维智慧创始人:17年心灵修行与素食·造就冻龄女神
  5. 单片机课程设计:基于STM32的温湿度检监测报警系统的设计
  6. 【2021最新版】《定时执行专家 5.2》软件使用手册
  7. python 识别登陆验证码图片(完整代码)
  8. Hexo+Kaze+Gitee Pages 搭建静态博客网站
  9. 【NOIP模拟】天使的分裂
  10. PCIE 设备在位检测机理