首页
统计
壁纸
追番记录
优秀博主
关于
推荐
导航
工具
音乐解锁
Search
1
NAS的简单介绍
775 阅读
2
网站环境一键部署工具推荐
506 阅读
3
tp5-模型数据处理
422 阅读
4
win10镜像
412 阅读
5
第20200225期-电脑壁纸-P10
350 阅读
PHP
闲谈杂料
硬件系统
美图
ThinkPHP
笔记
数据库
Lua
登录
Search
标签搜索
ThinkPHP
MySQL
Laravel
PHP
API
GIT
Windows10
markdown
Web
跨域
ajax
小程序
壁纸
Linux
jsonp
try
异常
Dcat
UEFI
win10
phpfunny
累计撰写
104
篇文章
累计收到
24
条评论
首页
栏目
PHP
闲谈杂料
硬件系统
美图
ThinkPHP
笔记
数据库
Lua
页面
统计
壁纸
追番记录
优秀博主
关于
推荐
导航
工具
音乐解锁
搜索到
1
篇与
的结果
2024-09-06
【Lua基础】元表与元方法
元表(metatable)lua中元表是用来存储元方法的表。我个人理解类似php中集合的概念但功能更多。元表拥有强大的特性:控制索引和赋值行为,控制算术运算,控制比较操作,控制调用行为,控制长度操作,控制转换行为,控制迭代行为,控制元表的更改。控制索引和赋值行为__index: 当尝试访问一个表中不存在的键时,Lua 会检查该表的元表是否定义了 __index 属性。如果定义了,则Lua会尝试根据这个属性提供的值来查找键。__newindex: 当尝试设置一个表中不存在的键时,Lua 会检查该表的元表是否定义了 __newindex 属性。如果定义了,则Lua会根据这个属性提供的值来处理这个赋值操作。控制算术运算__add, __sub, __mul, __div, __mod, __unm: 这些元方法允许你定义表和其他对象之间的算术运算行为。控制比较操作__eq, __lt, __le: 这些元方法允许你定义表之间的比较行为。控制调用行为__call: 允许你将表当作函数来调用。控制长度操作__len: 允许你定义表的长度(# 操作符)。控制转换行为__tostring, __concat: 这些元方法允许你在将表转换为字符串或与其他字符串拼接时定义行为。控制迭代行为__mode: 在Lua 5.2及更高版本中,此元方法允许你指定哪些字段应该使用next函数迭代时可见。控制元表的更改__metatable: 如果这个元方法存在,那么尝试更改一个表的元表时会调用这个方法。设置元表演示-- mytable = {} -- 普通表 mymetatable = {} -- 元表 setmetatable(mytable,mymetatable) -- 把 mymetatable 设为 mytable 的元表 --简写 mytable = setmetatable({},{})如果元表中有相同元数据,则可以进行加减操作演示两个表相加操作-- 自定义计算表中最大键值函数 table_maxn,即返回表最大键值 function table_maxn(t) local mn = 0 for k, _ in pairs(t) do if type(k) == "number" and k > mn then mn = k end end return mn end -- 两表相加操作 mytable = setmetatable({ 1, 2, 3 }, { __add = function(mytable, newtable) local max_key_mytable = table_maxn(mytable) for i = 1, table_maxn(newtable) do table.insert(mytable, max_key_mytable + i, newtable[i]) end return mytable end }) secondtable = {4, 5, 6} mytable = mytable + secondtable for k, v in ipairs(mytable) do print(k, v) end --输出结果 1 1 2 2 3 3 4 4 5 5 6 6其他:拓展展示使用元表来拓展表的功能-- 创建一个表 local myTable = { name = "example", value = 42 } -- 创建一个元表 local myMeta = { __index = { description = "This is an example table." }, __tostring = function(t) return string.format("Name: %s, Value: %d", t.name, t.value) end, __call = function(t, arg1, arg2) print("Called with:", arg1, arg2) end } -- 给myTable设置元表 setmetatable(myTable, myMeta) -- 访问不存在的键 print(myTable.description) -- 输出: This is an example table. -- 打印表 print(tostring(myTable)) -- 输出: Name: example, Value: 42 -- 调用表 myTable("Hello", "World") -- 输出: Called with: Hello World在这个例子中,我们定义了一个元表 myMeta,它包含了几个元方法来改变 myTable 的行为。通过设置 myTable 的元表为 myMeta,我们可以扩展 myTable 的功能,如定义其描述、改变其字符串表示形式,以及使其可调用。元表使得Lua中的表可以非常灵活,并且可以用来模拟面向对象编程中的类和继承的概念。通过适当的元表设计,你可以创建非常强大的数据结构和模式。在Lua中,__index 和 __newindex 是元表(metatable)中的两个特殊方法,用于实现表的继承和动态扩展功能。当一个表作为另一个表的元表时,这两个方法就变得非常重要。__index元方法__index是一个索引器,当尝试访问一个表中不存在的键时,Lua会检查该表的元表是否定义了__index属性。如果定义了,则Lua会尝试根据这个属性提供的值来查找键。如果 __index 是一个表,Lua会在那个表中查找键。如果 __index 是一个函数,Lua会调用该函数,并将表以及键作为参数传递给这个函数。示例local parent = { a = 1, b = 2 } local child = {} -- 设置parent为child的元表 setmetatable(child, { __index = parent }) print(child.a) -- 输出: 1 print(child.b) -- 输出: 2Lua 查找一个表元素时的规则:在表中查找,如果找到,返回该元素,找不到则继续判断该表是否有元表,如果没有元表,返回 nil,有元表则继续。判断元表有没有__index方法,如果__index方法为nil,则返回nil; 如果__index方法是一个表,则重复1、2、3; 如果__index方法是一个函数,则返回该函数的返回值。__newindex元方法__newindex与__index类似,但它是在尝试设置一个表中不存在的键时触发。如果设置了__newindex,Lua会根据它的值决定如何处理这个赋值操作。如果 __newindex是一个表,Lua会尝试在那个表中设置键的值。如果 __newindex是一个函数,Lua会调用该函数,并将表、键和要设置的值作为参数传递给这个函数。示例:假设我们想要记录每次对 child 表进行赋值的操作local parent = { a = 1, b = 2 } local meta = { __newindex = function(t, key, value) print("Setting " .. key .. " to " .. value) t[key] = value end } setmetatable(parent, meta) parent.c = 3 -- 输出: Setting c to 3 print(parent.c) -- 输出: 3 --在这个例子中,当我们尝试给parent表添加一个新的键c时, --__newindex定义的函数被调用,并且打印出一条消息,同时仍然允许赋值操作。总结:__index 用于处理读取不存在的键时的行为。__newindex 用于处理写入不存在的键时的行为。
2024年09月06日
7 阅读
0 评论
0 点赞