Lua语法小贴士(五)元表与元方法

Lua语法小贴士(三)魔法字符 介绍Lua里的魔法字符,用来对字符串进行模式匹配。 阅读详情

Lua里的元表(metatable)是指一套预定操作的集合,而这些操作称为元方法(metamethod)。

例如我们可以让两个数字相加,但是却没办法将两个table相加。如果想让表a加上表b,那么就需要使用元表里的__add元方法。

local tbl = {}
local mt = {}
mt.__add = function(a,b)
    return tbl.new(a.val + b.val)
end
function tbl.new(val)
    local t = {}
    setmetatable(t,mt)
    t.val = val
    return t
end

local a = tbl.new(1)
local b = tbl.new(2)
print((a+b).val)

元方法类似于c++里的运算符方法。

Lua里的算术操作除了__add之外,还有__mul(乘法)、__sub(减法)、__div(除法)、__unm(相反数)、__mod(取模)和__pow(乘幂)。此外还有__concat(连接)。

然后是关系操作:__eq(等于)、__lt(小于)和__le(小于等于),而对应的三种关系运算符(不等于,大于等于,大于)会通关前面的方法取反获得,不需要也不能实现。

接着是库定义的操作:__tostring(转字符串,print方法会自动调用这个元方法)

最后是访问操作:__index(索引)和__newindex(新索引),访问table的时候会优先访问table自身的索引,如果没有找到这个索引,会调用__index(查询)或__newindex(赋值)方法。

例如下面这段代码:

local tbl = {}
local mt = {
__index = function(t,k)
    print("index "..k)
    return rawget(t,k)
end,
__newindex = function(t,k,v)
    print("newindex "..k)
    rawset(t,k,v)
end
}
setmetatable(tbl,mt)
tbl.val = 1  --newindex val
tbl.val = 2
local val = tbl.val
local a = tbl.a --index a
我们可以借助这两个元反方实现一个只读的table:

local function readonly(t)
    local proxy = {}
    local mt = {
        _index = t,
        _newindex=function(t,k,v)
            error("!!Readonly!!", 2)
        end
    }
    setmetatable(proxy,mt)
    return proxy
end
local days = readonly({"Sun","Mon","Tue","Wed","Thu","Fri","Sat"})
print(days[1]) --Sun
days[2]="Noday" --!!Readonly!!
(此段代码改写自《Programming in Lua (Second Edition)》)

需要注意的两个点:

1、__index元方法可以直接使用原table代替函数,这样简单且高效。不过,需要每个只读代理都要创建一个新的元表。

2、这里使用了代理模式,可以参考小话设计模式(十二)代理模式

Lua语法小贴士(十一)debug库 Lua的调试库包含两种函数:自省函数和钩子。自省函数可以用来检查一个正在运行的程序的信息,而钩子可以跟踪程序的运行。 阅读详情

相关推荐

Lua语法小贴士(十)upvalue

我们都知道,Lua里面的function实际上都是闭包(closure),而upvalue便是它引用到的上下文变量(“引用到”三个字很关键),业界一般又称为外部局部变量(external local variable),如果要翻译的话,个人偏好翻译为“上文变量”。

凯奥斯的注释 3534

自由学习记录(25)

当试图给中不存在的键赋值时,Lua 会调用。

red_redemption的博客 1322

Lua语法小贴士(四)字符串缓冲

我们在写Lua代码的时候,如果需要对一个字符串进行反复的连接操作的话,会造成极大的性能开销。因为字符串是不可变的值,所以当我们对字符串操作的时候,每次都会生成一个新的字符串。例如我们需要对一个10000字节的字符串str增加一个字符的时候,就会创建一个10001字节的字符串str_copy,然后再复制str到str_copy里面。所以我们需要字符串缓冲(string buffer)来解决这个问题,而Lua里面,string buffer就可以使用table来实现。

凯奥斯的注释 1408

笔记: Lua基础: Metatable, 多重返回值, 迭代器

作者: apex.Cliz  <!--<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"xmlns:dc="http://purl.org/dc/elements/1.1/"xmlns:trackback="http://madskills.com/public/xml/rss/module/trackb

liuyukuan的专栏 3506

Lua 元表(Metatable)

1.在中查找,如果找到,返回该素,找不到则继续2.判断该是否有元表,如果没有元表,返回 nil,有元表则继续。3.判断元表有没有 __index 方法,如果 __index 方法为 nil,则返回 nil;如果 __index 方法是一个,则重复 1、2、3;如果 __index 方法是一个函数,则返回该函数的返回值。该部分内容来自作者寰子:https://blog.csdn.net/xocoder/article/details/9028347。

jiangzhmi的博客 1509

Lua中的元表方法

前言Lua中每个值都可具有元表元表是普通的Lua,定义了原始值在某些特定操作下的行为。你可通过在值的原中设置特定的字段来改变作用于该值的操作的某些行为特征。例如,当数字值作为加法的操作数时,Lua检查其元表中的"__add"字段是否有个函数。如果有,Lua调用它执行加法。我们称元表中的键为事件(event),称值为方法metamethod)。前述例子中的事件是"add",方法是执行加

小枫的专栏 2680

lua元表方法

lua元表方法

伟庭的博客 1766

Lua语法小贴士(十)全局变量

Lua里我们可以随时声明或调用全局变量。 虽然很方便,但是往往会因为拼写错误而导致一些不容易发现的BUG。 Lua可以使用_G来示全局变量所在的,这样我们就可以修改_G的__index和__newindex两个方法(参考Lua语法小贴士元表方法)来限制全局变量的访问。

凯奥斯的注释 1308

Lua语法小贴士(二)string库

Lua语言string库方法介绍。

凯奥斯的注释 2407

Unity3D开发小贴士(六)Lua里调用C#扩展

C#语法小知识(八)扩展介绍过如何扩展C#的类型,Unity3D开发小贴士Lua调用C#里介绍了如何使用ToLua插件在Lua脚本里调用C#代码。那么本文介绍一下如何在Lua里调用C#类型的扩展方法

凯奥斯的注释 3946

Lua语法小贴士(六)迭代器

Lua里面可以使用for in语句来遍历table,一般会使用内置的ipairs或pairs方法,而这两个方法会返回迭代器(关于迭代器的相关理论知识,参考小话设计模式(十)迭代器模式)。本文就介绍一下如何自定义迭代器。

凯奥斯的注释 981

Lua语法小贴士(十四)垃圾回收collectgarbage

Lua垃圾回收只有一个函数collectgarbage,第一个参数是字符串,代操作类型,第二个参数只有某些操作有,是该操作所需要的参数。

凯奥斯的注释 1万+

Lua方法

方法功能参数返回值__index访问不存在的键table,key键的值__newindex拦截不存在的键的赋值无__add重载加法运算符+a,b加法结果__concat重载字符串连接运算符..a,b连接结果__call定义被调用时的行为...调用结果__tostring自定义的字符串示table字符串保护元表无保护值或nil通过方法,可以深度自定义Lua的行为,从而实现更多高级的功能。

nanyupeng的博客 1563

lua元表

Lua中,元表Metatable)是一种用于定义或修改(table)在特定操作下的行为的机制。元表中的字段(通常以双下划线__开头)被称为方法Metamethod)。以下是一些常见的__xxx。

weixin_46484046的博客 1599

深入 Lua 元表方法

本文深入解析Lua元表(metatable)的核心概念应用。元表通过方法(metamethod)扩展Lua值的行为,使table支持算术运算、自定义比较等高级特性。重点讲解了setmetatable/getmetatable的使用方法、算术和关系类方法的实现(如__add、__eq)、库定义方法(__tostring、__metatable)以及table访问方法(__index和__newindex)的分工协作。通过集合运算、继承实现、只读table等案例,展示了元表如何突破Lua默认行为限制,

2401_83191546的博客 1040

lua--table、元表metatable方法

lua--table元表metatable方法table使用table存储数组使用table存储键值对(hash结构)上述可见table使用两种方式存储数据table数据结构源码元表metatable方法通过__index和__newindex实现一个只读table table table是lua强大的数据结构,靠table就可以运用在大部分场景。 我们先简单的看下table的使用方式。 使用table存储数组 a = {} --这是一个名为a的空table b = {1,2,3,4,5} --这

whibalck的博客 743

Lua中的元表方法

元表可以修改一个值的行为,使其在面对一个非预定义的操作时执行一个指定操作。 方法会检测一个操作中的值是否有元表,以及元表是否定义了操作的方法。如两个table相加,先检查两者之一是否有元表,之后检查是否有一个叫“__add”的字段,若找到,则调用对应的值。“__add”等字段,其对应的值(一般是一个函数或是table)就是“方法”。

陈嘉怡的专栏 2607

Lua 元表方法

lua 元表方法

Willieying的博客 1357
上一篇: Shader山下(十七)语义Semantic
下一篇: Shader山下(十八)混合(Blend)命令
凯奥斯
凯奥斯 领域专家: 游戏开发技术领域 领域专家: 游戏开发技术领域
博客等级 码龄16年 1297粉丝 157原创
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值