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. Openstack的打包方法

    使用setup.cfg和setup.py进行管理 1.setup.py文件内容 # THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO ...

  2. Python的classmethod和staticmethod区别

    静态方法(staticmethod) 类方法(classmethod) 静态方法和类方法都可以通过类名.方法名或者实例.方法访问. #-*- coding:utf8 -*- class A(objec ...

  3. shell脚本 案例

    1,写一个循环,ping整个子网的ip.   使用while循环 #!/bin/bash  ip=223  while [ "$ip" -ne "239" ] ...

  4. jq实现全选或者全不选

    $("#all").click(function () { if($(this).is(":checked")){ $("input[name='pr ...

  5. cocos2dx3.2移植android

    LOCAL_PATH := $(call my-dir)LOCAL_MYDIR = $(LOCAL_PATH)/../../Classesinclude $(CLEAR_VARS) $(call im ...

  6. OC的特有语法-分类Category、 类的本质、description方法、SEL、NSLog输出增强、点语法、变量作用域、@property @synthesize关键字、Id、OC语言构造方法

    一. 分类-Category 1. 基本用途:Category  分类是OC特有的语言,依赖于类. ➢ 如何在不改变原来类模型的前提下,给类扩充一些方法?有2种方式 ● 继承 ● 分类(Categor ...

  7. java 之 建造者模式(大话设计模式)

    建造者模式,在笔者看来比较试用于,定制一个业务流程,而流程的细节又不尽相同,每个细节又必不可少,这时应考虑使用建造者模式. 大话设计模式-类图 先看下笔者写的一个简单的例子. /** * 所有建造过程 ...

  8. sublime3配置php环境

    最后的演示效果: 1. 按照sublime3开始前的准备工作 Ctrl+Shift+P,再输入install ,最后再输入想要安装的软件 (输入install会有几十秒的延迟,请不要重复操作) 配置p ...

  9. C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址

    C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址 讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了,当 ...

  10. SSD: Single Shot MultiBoxDetector英文论文翻译

    SSD英文论文翻译 SSD: Single Shot MultiBoxDetector 2017.12.08    摘要:我们提出了一种使用单个深层神经网络检测图像中对象的方法.我们的方法,名为SSD ...