分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 运营维护

Lua——3.元表Metatable

发布时间:2023-09-06 01:43责任编辑:白小东关键词:暂无标签

lua的metatable也是一个普通的表,lua提供metatable的功能,主要有一下几种作用:

  1. 控制对 table 的访问
  2. 为 Lua 函数库提供支持
  3. 重载算数运算符和关系运算符的行为

    1.使用metatable控制对table的访问

    当查询table的某个键的时候,如果该table的这个键没有值,那么Lua就会寻找该table的metatable中的__index元方法:如果__index指向一个table,Lua会在此table中查找相应的键, 并且,__index也可以指向一个方法

当对table的某个键进行赋值时,如果该table存在该字段则为之赋值,若没有,那么Lua就会寻找该table的metatable中的__newindex元方法:如果__newindex指向一个table时,Lua会对这个table进行赋值操作,如果__newindex指向一个方法,Lua则会调用该方法

lua中的__index元方法
如果__index包含一个表格,Lua会在此表格中查找相应的键。
并且,__index可以指向一个表也可以指向一个方法

__index指向表时:
之前我们需要知道,当我们在一个表中查找一个元素时
首先在该表中查找,有则返回对应值,无则查看该表是否有元表metatable
若无元表则返回nil
有元表时,lua并不是在其元表中查找,而是在其元表的__index域中查找
因此:仅使用setmetatable()方法设置元表,并不能取得对应元表中的元素

BaseClass = {theKey1 = "the string value1"}--[[DerivedClass = {}setmetatable(DerivedClass,BaseClass)]]----注释的两句可简写为:DerivedClass = setmetatable({},BaseClass)res = DerivedClass.theKey1print(res)

设置对应元表的__index键之后:

BaseClass = {theKey1 = "the string value1"}BaseClass.__index = BaseClassDerivedClass = setmetatable({},BaseClass)res = DerivedClass.theKey1print(res)

也可以换一种简写方法:

BaseClass = {theKey1 = "the string value1"}DerivedClass = setmetatable({},{__index = BaseClass}) ???--即直接设 ?AnonymousTable = {__index = BaseClass} 为DerivedClass的元表,查找时可直接在AnonymousTable中的__index域对应的表BaseClass中查找res = DerivedClass.theKey1print(res)

所以,lua中的继承可以表示为:

local Car = {}Car.__index = Carfunction Car:new(o) ???o = o or {} ???setmetatable(o,Car) ???return oendfunction Car:run() ???print("Car‘s run func.")end--直接调用“父类”中的run方法Car.run()local FordCar = Car:new()--子类调用“父类”中的run方法FordCar.run()--重写fordCar中的run方法function FordCar:run() ???print("FordCar‘s run func.")end--重写之后调用FordCar.run()

__index指向一个方法时
__index指向一个方法时,在我们访问该 table 的不存在的域时,Lua 会尝试调用 __index 元方法metamethod (__index metamethod 可以接受两个参数 table 和 key)

local t1 = {}t1.__index = function(table,key) ???print("call the __index metamethod") ???print("table"..tostring(table)) ???print("key"..key) ???return key.." from the __index"end--set t1 as t2‘s metatablelocal t2 = setmetatable({},t1)--pass the table and the key to __indexmetamethodlocal res = t2.key1print("the result is :"..res)print("------------------")res = t2.key2print("the result is :"..res)

__newindex元方法
如果对 table 的一个不存在的域赋值时,Lua 将检查 __newindex metamethod:

1.如果 __newindex 为函数,Lua 将调用函数而不是进行赋值(如果 __newindex 为一个函数,它可以接受三个参数 table key value。如果希望忽略 __newindex 方法对 table 的域进行赋值,可以调用 rawset(t, k, v))
2.如果 __newindex 为一个 table,Lua 将对此 table 进行赋值

--file:newindex.lualocal mt = { ???key1 = "key1‘s value"}local other = { ???key1 = "the old value"}mt.__index = mt--[[mt.__newindex = function() ???print "Can not set value"end--]]mt.__newindex = other local t = setmetatable({},mt)t.key1 = "the new value from the table t."print(t.key1)--对__newindex指向的table中的key1进行更新操作,但是table t 中仍然没有键key1,进行t.key1的查询时,查询的仍然是__index中对应的键key1的值print(other.key1)

2. 为 Lua 函数库提供支持

Lua 库可以定义和使用 metamethod 来完成一些特定的操作
一个典型的例子是 Lua Base 库中 __tostring 函数,print 函数会调用此函数进行输出,调用print时,会检查并调用 __tostring metamethod

--file:tablelib.lualocal mt = {}mt.__tostring = function(t) ???return ‘{‘..table.concat(t,‘,‘)..‘}‘endlocal t = {1,2,3}print(t)print("-----------------")setmetatable(t,mt)print(t)

3. 重载算数运算符和关系运算符的行为

//TODO 

Lua——3.元表Metatable

原文地址:https://www.cnblogs.com/sylvan/p/8478366.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved