Lua 元表(Metatable)

在 Lua table 中我们可以访问对应的key来得到value值,但是却无法对两个 table 进行操作。

个人理解,这个相当于其他语言的继承,是把这个类的方法和属性塞进新的表里面。

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

例如,使用元表我们可以定义Lua如何计算两个table的相加操作a+b。

当Lua试图对两个表进行相加时,先检查两者之一是否有元表,之后检查是否有一个叫"__add"的字段,若找到,则调用对应的值。"__add"等即时字段,其对应的值(往往是一个函数或是table)就是"元方法"。

有两个很重要的函数来处理元表:

setmetatable(table,metatable): 对指定table设置元表(metatable),如果元表(metatable)中存在__metatable键值,setmetatable会失败 。

getmetatable(table): 返回对象的元表(metatable)。

以下实例演示了如何对指定的表设置元表:

__index参考示例

local a1 = { 20, 1, key1 = "hello_a1", key2 = "world_a1", lang = "lua" }
print("the table a1:")
for _, v in pairs(a1) do
print(v)
end --[输出结果]
--the table a1:
--20
--1
--hello_a1
--world_a1
--lua local a2 = {
key1 = "hello_a2",
key2 = "world_a2"
} print("the old table a2:")
for _, v in pairs(a2) do
print(v)
end --[输出结果]
--the table a2:
--hello_a2
--world_a2 print("a2的metatable:", getmetatable(a2))
print("language:", a2["lang"]) --[输出结果]
--a2的metatable: nil
--language: nil -- 关注函数及__index
setmetatable(a2, { __index = a1 }) print("the new table a2:")
for _, v in pairs(a2) do
print(v)
end --[输出结果]
--the new table a2:
--hello_a2
--world_a2 print("language:", a2["lang"]) --[输出结果]
--language: lua print("a2数组第一个元素:", a2[1])
print("a2的metatable:", getmetatable(a2)) --[输出结果]
--a2数组第一个元素: 20
--a2的metatable: table:0x5A8E6888

大家可以参考lua手册,metatable是被译作元表,Lua 中的每个值都可以用一个 metatable。这个 metatable 就是一个原始的 Lua table ,它用来定义原始值在特定操作下的行为。

一个 metatable 可以控制一个对象做数学运算操作、比较操作、连接操作、取长度操作、取下标操作时的行为,metatable 中还可以定义一个函数,让 userdata 作垃圾收集时调用它。对于这些操作,Lua 都将其关联上一个被称作事件的指定健。当 Lua 需要对一个值发起这些操作中的一个时,它会去检查值中 metatable 中是否有对应事件。如果有的话,键名对应的值(元方法)将控制 Lua 怎样做这个操作。

连接符对应的操作

metatable通过其包含的函数来给所挂接的table定义一些特殊的操作,包括:

__unm: 定义负操作, 即: -table的含义

__tostring: 定义当table作为tostring()函式之参数被呼叫时的行为(例如: print(table)时将呼叫tostring(table)作为输出结果)

__index: 定义当table中不存在的key值被试图获取时的行为

__newindex: 定义在table中产生新key值时的行为

模式 对应操作符 描述
__add 对应的运算符 '+' 定义所挂接table的加法操作
__sub 对应的运算符 '-' 定义减法操作
__mul 对应的运算符 '*' 定义乘法操作
__div 对应的运算符 '/' 定义除法操作
__mod 对应的运算符 '%' ...
__unm 对应的运算符 '-'(负) 定义负操作, 即: -table的含义
__concat 对应的运算符 '..' 定义连接操作(".."运算符)
__eq 对应的运算符 '==' ..
__lt 对应的运算符 '<'
__le 对应的运算符 '<='

__tostring参考示例

local table1 = {10, 20, 30}

local table2 = {}
table2.__tostring = function(myTable)
local sum = 0
for _, v in pairs(myTable) do
sum = sum + v
end
return ("表元素之和=" .. sum)
end setmetatable(table1, table2)
print(table1) --[输出结果]
--表元素之和=60

参考资料及推荐阅读

http://www.runoob.com/lua/lua-metatables.html
http://blog.csdn.net/eckelwei/article/details/9299899
http://www.cnblogs.com/JimLy-BUG/p/5364281.html

学习Lua setmetatable Lua 元表的更多相关文章

  1. Lua中的元表与元方法学习总结

    前言 元表对应的英文是metatable,元方法是metamethod.我们都知道,在C++中,两个类是无法直接相加的,但是,如果你重载了"+"符号,就可以进行类的加法运算.在Lu ...

  2. 【游戏开发】小白学Lua——从Lua查找表元素的过程看元表、元方法

    引言 在上篇博客中,我们简单地学习了一下Lua的基本语法.其实在Lua中有一个还有一个叫元表的概念,不得不着重地探讨一下.元表在实际地开发中,也是会被极大程度地所使用到.本篇博客,就让我们从Lua查找 ...

  3. Lua中的元表与元方法

    [前言] 元表对应的英文是metatable,元方法是metamethod.我们都知道,在C++中,两个类是无法直接相加的,但是,如果你重载了“+”符号,就可以进行类的加法运算.在Lua中也有这个道理 ...

  4. Lua中的元表和元方法

    Lua中每个值都可具有元表. 元表是普通的Lua表,定义了原始值在某些特定操作下的行为.你可通过在值的原表中设置特定的字段来改变作用于该值的操作的某些行为特征.例如,当数字值作为加法的操作数时,Lua ...

  5. uLua 学习笔记 之一 lua脚本 打包与读取

    最近要学习热更新,搜了下,选择了ulua这个插件,本人也是新人.对这个插件也是一知半解,不过幸好加了专门讨论这一块的群,这个群的技术氛围还是很浓重的,特别是已经形成了一套自己的lua学习框架.最近周末 ...

  6. Nginx详解二十二:Nginx深度学习篇之Lua解释器安装及基础语法

    解释器 Lua:Lua是一个简洁.轻量.可扩展的脚本语言 Nginx+Lua优势充分的结合Nginx的并发处理epoll优势的Lua的轻量实现简单的功能切高并发的场景 安装Lua 1.安装解释器:yu ...

  7. 优雅的使用sublime写lua~ sublime lua相关必装插件推荐~~

    缘起 lua脚本语言虽好,代码写得飞快,可是写错了调试起来却很困难,lua使用者经常容易犯得一个错误是--写错变量名了,if end 嵌套太多没匹配~,多打了一个逗号, 假设定义了一个变量 local ...

  8. [转]Lua和Lua JIT及优化指南

    一.什么是lua&luaJit lua(www.lua.org)其实就是为了嵌入其它应用程序而开发的一个脚本语言, luajit(www.luajit.org)是lua的一个Just-In-T ...

  9. This module embeds Lua, via LuaJIT 2.0/2.1, into Nginx and by leveraging Nginx's subrequests, allows the integration of the powerful Lua threads (Lua coroutines) into the Nginx event model.

    openresty/lua-nginx-module: Embed the Power of Lua into NGINX HTTP servers https://github.com/openre ...

随机推荐

  1. MySQL5.6的optimizer_trace

    MySQL的explain是各种执行计划选择的结果,如果想看整个执行计划以及对于多种索引方案之间是如何选择的? MySQL5.6中支持这个功能,optimizer_trace 这个是mysql的参数, ...

  2. 数据库中File权限的危害

    The FILE privilege gives you permission to read and write files on the server host using the LOAD DA ...

  3. Django 入门案例开发(中)

    昨天已经描述了如何搭建Django的开发环境,今天描述业务流程,具体我们要实现一个什么样的业务: 以下的业务都是假设的(网上书店   页面做的low): 1.用户注册及登录业务: 这是一个网上书店阅读 ...

  4. 原码、反码、补码的正(nao)确(can)打开方式

    我们知道日常生活中使用的数分为整数和实数,整数的小数点固定在数的最右边,可以省略不写,而实数的小数点则不固定.在计算机中只能识别和表示“0”和“1”,而无法识别小数点,因此要想使得计算机能够处理日常使 ...

  5. Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法

    找到Help Viewer程序的位置(可以使用Everything工具搜索microsoft help找到),发送到桌面快捷方式,打开此快捷方式的属性,在目标的最后添加下面那行字,然后即可通过快捷方式 ...

  6. 用Python写一款属于自己的 简易zip压缩软件 附完成图(适合初学者)

    一.软件描述 用Python tkinter模块写一款属于自己的压缩软件.zip文件格式是通用的文档压缩标准,在ziplib模块中,使用ZipFile来操作zip文件,具有功能:zip压缩功能,zip ...

  7. 但未在用户代码中进行处理 具有固定名称“Oracle.ManagedDataAccess.Client”的 ADO.NET 提供程序未在计算机或应用程序配置文件中注册或无法加载。

    这是使用ODP.NET链接Orcl数据库常见错误,需要配置系统环境变量. 解决方法如下: 找到以下路径文件:C:\Windows\Microsoft.NET\Framework\v4.0.30319\ ...

  8. struct 类型指针技巧

    此类型对于两种结构的查找和删除都十分方便,实际项目中也常常用到.

  9. nefu 115 循环节

    斐波那契的整除 Problem:115 Time Limit:1000ms Memory Limit:65536K Description 已知斐波那契数列有如下递归定义,f(1)=1,f(2)=1, ...

  10. 负载均衡之nginx

    什么是负载均衡负载均衡(Load Balance)是分布式系统架构设计中必须考虑的因素之一,它通常是指,将请求/数据[均匀]分摊到多个操作单元上执行,负载均衡的关键在于[均匀].在使用nginx负载均 ...