Lua学习笔记 — Table与Metatable(超详细)

01、Table

table是lua 中唯一的数据结构;既可以表示 hashtable 也可表示为 array;配合元表可以定制表复杂的功能(如实现面对对象编程中的类以及相应继承的功能)

数组

arr1 = {1,2,"abc"}
-- table.insert(table, [pos,] value) table 是要插入元素的表,pos 是可选参数,表示要插入的位置,默认为表末尾,value 是要插入的元素。
table.insert(arr1,3,33) -- 插入数据
--  遍历数组 在 Lua 索引值是以 1 为起始
for index, value in ipairs(arr1) doio.write("index=",index," value=",value," ") -- 打印打印不换行-- 运行结果:index=1 value=1 index=2 value=2 index=3 value=33 index=4 value=abc
end
print()
arr2 ={{1,11,111,1111,11111},{2,22,222,2222}
}
-- table.remove(list [, pos]) list 表示要进行删除操作的表,pos 表示要删除的元素的位置。如果没有指定 pos 参数,则默认删除表中的最后一个元素。
table.remove(arr2[2],2)
-- 可以使用#获取数组长度  type(arr2)获取数据类型
print("arr2[1][2]",arr2[1][2],"arr2.length",#arr2,"arr2[2].length",#arr2[1],type(arr2))-- 运行结果:arr2[1][2]  11  arr2.length  2   arr2[2].length 2   table

hashTable

dict = {k1 = "v1",k2 = "10086",k3 = "v3"
}
-- table.insert(dict,3,666) bad argument #2 to 'insert' (position out of bounds) 置超出了表的长度范围 (table.insert 函数无法直接用于 Lua 中的字典(或称为键值对)。table.insert 函数用于操作数组形式的表,而不是字典)
table.insert(dict,1,666) 
dict["age"] = 18
dict[10] = "v4"table.remove(dict,2) -- 不会删除,因为不存在索引为2的数据(table.remove不能根据key来删除value,需要自己写代码实现根据key删除value)
print(dict.k1,dict.k2,dict["age"],dict["k3"],dict.k4)
-- pairs函数会遍历表的所有键值对,并按照任意顺序返回键和对应的值
-- ipairs函数则用于遍历数组部分的表项。它只会遍历连续的整数键,并按照索引顺序返回索引和对应的值。
-- 这里不能用ipairs进行遍历
for index, value in pairs(dict) doio.write("key=",index," value=",value," ") 
end
print()
-- 获取 table 的长度的时候无论是使用 # 还是 table.getn 其都会在索引中断的地方停止计数,而导致无法正确取得 table 的长度。如果需要
print(#dict)

运行结果

v1      10086   18      v3      nil
key=1 value=666 key=10 value=v4 key=k2 value=10086 key=k1 value=v1 key=age value=18 key=k3 value=v3 
1

02、元表(Metatable)

在Lua中,每个table都可以关联一个metatable。metatable是一个普通的table,可以包含一些特殊的字段(也称为元方法),这些字段定义了对应操作的行为。通过设置metatable,我们可以对table对象进行元操作的重载,实现自定义的行为。

常用元方法

  • __index:当访问一个table中不存在的索引时触发。
  • __newindex:当给一个table中不存在的索引赋值时触发(赋值会失败)。
  • _gc :元表中用一个以字符串 " gc " 为索引的域,那么就标记了这个对象需要触发终结器;
  • __add、__sub、__mul、__div等:用于重载算术操作符的行为,比如加法、减法、乘法、除法等。
  • __eq、__lt、__le:用于重载比较操作符的行为,比如相等、小于、小于等于等。
  • __tostring:用于将table转换为字符串的元方法。
  • __call:当一个table被当作函数调用时触发,可以通过该元方法使table对象具备函数的行为。

Demo

local tab = {k1 = "v1",k2 = "10086",k3 = "v3"
}local meTab = setmetatable(tab,{__index = function (t, key)print("_index tab.k1=",t.k1,"key=",key)return "not find key"end,__newindex = function (t, key, value)-- table.insert(t,key,value) 在这里调用insert方法也不会插入成功print("__newindex key=",key,"value=",value)end,__gc =  function ()print("++++++++gc+++++++++++")end
})print(myTab["ss"])
myTab["sss"] = "vaa"
table.insert(myTab,1,"v11")
for key, value in pairs(myTab) doio.write("key=",key," value=",value," ") -- 打印打印不换行
end
print()

运行结构

_index tab.k1=  v1      key=    ss
not find key
__newindex key= sss     value=  vaa
__newindex key= 1       value=  v11
key=k2 value=10086 key=k1 value=v1 key=k3 value=v3  # 赋值与insert失败
++++++++gc+++++++++++

03、Demo基于Table实现队列

local Queue = {}function Queue:init()local queueData = {data = {}, head = 1, tail = 0}-- 通过setmetatable(queueData, self) 将 queueData对象与 Queue 类关联起来,并设置元表,使 queueData对象可以调用Queue类中定义的方法。setmetatable(queueData, self) -- self.__index = self 设置对象的元表中的 __index 元方法,将其指向自己。目的是,在对象访问属性或方法时,如果对象本身没有该属性或方法,就会去访问元表的 __index 中指定的对象,以实现属性和方法的继承。self.__index = selfreturn queueData
endfunction Queue:isEmpty()return self.head > self.tail
endfunction Queue:push(value)self.tail = self.tail + 1self.data[self.tail] = value
endfunction Queue:pop()if self:isEmpty() thenreturn nilendlocal value = self.data[self.head]self.data[self.head] = nilself.head = self.head + 1return value
end

使用

local myQueue = Queue:init()
myQueue:push(1)
myQueue:push("abc")
myQueue:push({1,2,3})print(myQueue:pop())  -- 1
print(myQueue:pop())  -- abc
print(myQueue:pop())  -- table: 0x55be51926b00

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/226842.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《地理信息系统原理》笔记/期末复习资料(11. GIS的输出与地图可视化)

目录 11. GIS的输出与地图可视化 11.1. GIS的输出 11.1.1. 输出方式 11.1.2. GIS的图形输出设备 11.2. 地图符号 11.2.1. 地图符号的实质 11.2.2. 地图符号的分类 11.2.3. 地图符号的设计要求 11.3. 专题信息表达 11.3.1. 专题地图的基本概念 11.3.2. 专题地图的表示…

2023.12面试题汇总小结

文章目录 Java字节码都包括哪些内容Java双亲委派机制如何打破Java Memory Model是什么synchronized的锁优化是什么CountDownLatch、CyclicBarrier、Semaphore有啥区别,什么场景下使用MySQL MVCC原理MySQL RR隔离级别,会出现幻读吗MySQL的RR隔离级别下&am…

L1-030 一帮一(Python3)

“一帮一学习小组”是中小学中常见的学习组织方式,老师把学习成绩靠前的学生跟学习成绩靠后的学生排在一组。本题就请你编写程序帮助老师自动完成这个分配工作,即在得到全班学生的排名后,在当前尚未分组的学生中,将名次最靠前的学…

boost graph之基础

结构 属性相关 #mermaid-svg-LUDFVluXTOlnqK0d {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-LUDFVluXTOlnqK0d .error-icon{fill:#552222;}#mermaid-svg-LUDFVluXTOlnqK0d .error-text{fill:#552222;stroke:#5522…

微软自带浏览器Edge,无法关闭“保存历史记录网站的屏幕截图”解决方案

微软自带浏览器Edge,无法关闭“保存历史记录网站的屏幕截图”解决方案 吐槽1:Windows自带的Chrome内核版本的浏览器Microsofg Edge刚发布时可谓一股清流,启动速度快,占用内存较小,相信很多人也开始抛弃正代Chrome&…

springboot实战项目之使用AOP技术实现各种角色的鉴权功能

前言 项目开发需求,会员有不同的角色,不同的角色被赋予不同的权限,这就需要对会员的操作进行鉴权处理。 方案 采用aop,可实现满足这种需求,创建匿名类。对外提供接口的时候都会拦截,这种会有弊端&#x…

【Spring】08 BeanNameAware 接口

文章目录 1. 简介2. 作用3. 使用3.1 创建并实现接口3.2 配置 Bean 信息3.3 创建启动类3.4 启动 4. 应用场景总结 Spring 框架为开发者提供了丰富的扩展点,其中之一就是 Bean 生命周期中的回调接口。本文将聚焦于其中的一个接口 BeanNameAware,介绍它的作…

Hudi 在 vivo 湖仓一体的落地实践

作者:vivo 互联网大数据团队 - Xu Yu 在增效降本的大背景下,vivo大数据基础团队引入Hudi组件为公司业务部门湖仓加速的场景进行赋能。主要应用在流批同源、实时链路优化及宽表拼接等业务场景。 一、Hudi 基础能力及相关概念介绍 1.1 流批同源能力 与H…

大数据-MapReduce-关于Json数据格式的数据的处理与练习

目录 🐶16.1 Json是什么? 🐶16.2 Json的语法规则 🐶16.3 JSON 和 XML 🐶16.4 java中关于json中的jar包 🥙GSON:由谷歌进行开发 🥙Fastjson: 由阿里进行开发 &…

go学习redis的学习与使用

文章目录 一、redis的学习与使用1.Redis的基本介绍2.Redis的安装下载安装包即可3.Redis的基本使用1)Redis的启动:2)Redis的操作的三种方式3)说明:Redis安装好后,默认有16个数据库,初始默认使用0…

最流行的视频创作者

说在前面 🎈不知道大家对于算法的学习是一个怎样的心态呢?为了面试还是因为兴趣?不管是出于什么原因,算法学习需要持续保持。 题目描述 给你两个字符串数组 creators 和 ids ,和一个整数数组 views ,所有数…

C语言之实现贪吃蛇小游戏篇

text.c #define _CRT_SECURE_NO_WARNINGS 1 #include "snake.h" void test() {int ch 0;do{Snake snake { 0 };//创建了贪吃蛇//1. 游戏开始 - 初始化游戏GameStart(&snake);//2. 游戏运行 - 游戏的正常运行过程GameRun(&snake);//3. 游戏结束 - 游戏善后…

2023-12-15 Fri

坚持打卡第47天 健康方面(非常重要‼️) 每天运动,有氧和拉伸为主,运动十几分钟即可✅(1h)零点之前睡觉早上八点之前起床✅ 学习方面 力扣每日一题✅每天把当天APP上的单词复习完,并复习至少…

java导出word使用模版与自定义联合出击解决复杂表格!

1. 看一下需要导出什么样子的表格 如图所示,这里的所有数据行都是动态的,需要根据查询出来的数据循环展示。 如果只是这样的话,使用freemarker应该都可以搞定,但是他一列中内容相同的单元格,需要合并。 这对于表格样式…

conda命令克隆(复制)环境

前情介绍 最近有个需求是:根据已有的环境生成一个新的环境,也就是所需的新环境有大多数包和已有的环境都是相同的,需要改的只是部分,所以呢,克隆一个就再适合不过了! 所需命令 conda create -n B --clone…

java设计模式-工厂方法模式

1.工厂方法(FactoryMethod)模式的定义 定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。 2.工厂方法模式的主要优缺点 优点: 用户只需要知道具体工厂的名称…

HPM6750系列--第九篇 GPIO详解(基本操作)

一、目的 在之前的博文中我们主要介绍了不同系统不同开发编译调试环境的配置和操作(命令行方式、Visual Studio Code、Segger Embedded Studio for RISC-V),以帮助大家准备好学习环境为目的,但是未涉及到芯片本身以及外设的讲解。…

【linux】图形界面Debian的root用户登陆

图形界面Debian默认不允许以root用户登录。这是出于安全考虑,以防止用户使用root权限执行可能损害系统的操作。 如果需要使用root用户,可以通过以下步骤进行登录: 打开终端,使用su命令切换到root用户。修改/etc/gdm3/daemon.con…

大型网站架构演进过程

架构演进 大型网站的技术挑战主要来自于庞大的用户,高并发的访问和海量的数据,任何简单的业务一旦需要处理数以P计的数据和面对数以亿计的用户,问题就会变得很棘手。大型网站架构主要就是解决这类问题。 架构选型是根据当前业务需要来的&…