[lua]紫猫lua教程-命令宝典-L1-01-07. table表
L1[table]01. table表的定义与赋值
小知识:声明表的例子
xx={}--创建一个空表xx --给这表的元素赋值 test="a" xx[test]="a" xx.b="b" xx.c="c" xx.d="d" xx["e"]="e" ---输出对应的表元素的值 traceprint(xx[test]) traceprint(xx.e) --简单遍历整个表 for k,v in pairs(xx) do traceprint(k,"->",v) end
注意:表的键key不能是nil 会报错的 如果key是变化的或者某个变量 在用的时候一定要先判断key是不是nil 一定要考虑这个情况
报错信息:D:\Program Files (x86)\zerobrane\bin\lua53.exe: E:\lua\test7.lua:12: table index is nil .
L1[table]02. table的按址传递。
小知识:普通变量赋值 和表的赋值是完全不同的 对于表的相互赋值有重大影响
a=10
b=a --这里是把a变量的内容10拷贝了一份到了b变量的内存地址里面
a={1,2,3}
b=a --表的赋值 只是把a变量这个表的内存地址 也转给了b变量 如下 单单输出表xx 和表yy 他们 的内容都一样 而且都是指向同一个内存地址 一旦表xx的元素发生变化 因为表xx表yy都是指向同一个内存地址 不是拷贝了一份内容到另外1个内存地址 表xx的元素发生变化 表yy自然也会变动 我个人理解 表xx 表yy其实都是类似c语言下的指针 这个xx yy变量不是存储表元素的内容 而是只是存储记录表元素内容的内存地址 两个表之间的赋值 其实也就是传址
xx={}--创建一个空表xx traceprint(xx) --table: 00fc9158 显示的是该表在内存的存储地址 而不是表中的变量 yy=xx traceprint(yy) --table: 00fc9158
核心:表变量内容只是一个指针 里面存储的是指向表内容存储的内存地址 所以 表之间相互的赋值 不过是新表变量获取了一个存储原内容存储的地址而已
解决办法:真要实现完美的表的复制 可以用clone函数来实现
小知识:两个表都指向同一个表地址 一个表为nil 另外一个表是否会受到影响
xx={}--创建一个空表xx traceprint(xx) --table: 00fc9158 显示的是该表在内存的存储地址 而不是表中的变量 yy=xx traceprint(yy) --table: 00fc9158 xx=nil traceprint(xx) --nil 这里只是把表变量xx的内容里面存储的指向表内容的地址 变为nil 但是对指向表内容却没有任何影响 traceprint(yy) --table: 00fc9158
结论 自然是不会 因为设置xx=nil只是把xx指向真正表内容的内存地址清空为nil了 更没影响表内容内存地址里面的东西 但是yy里面依然记得这个内存地址
小知识:那么如何清空表 节约系统资源
只需要把指向该表内容的内存地址的指针变量都设置为nil 虽然表的内容依然存在 但是lua有自动回收机制 这种没有任何指针指向的内存地址内容 自然是在被回收的范围
L1[table]03. table的小数点取值
没什么 不过是引用表元素的表达形式不同而已
xx[“a”] ==>xx.a
当然 键key 必须是字符串 如果是数值 就无法如此表示了
注意:xx={1,2,3,qq=”234234234”} 注意 以这种形式 qq这个key不能加引号
稍微提一下 xx={1,2,3,qq=”234234234”} 还有另外1个形式可以写 xx={1,2,3,[“qq”]=”234234234”}
小知识:表索引的默认key 没有指定key的 从左到右从1开始数字索引
L1[table]04. table构造器与数组
注意:以前没有注意 遍历表 如果表是nil 整个代码会报错 如果考虑稍微完善一点就是下面的代码 避免代码崩溃
报错信息 D:\Program Files (x86)\zerobrane\bin\lua53.exe: E:\lua\test7.lua:24: bad argument #1 to 'pairs' (table expected, got nil)
--考虑的稍微完善的简单遍历整个表 if (not zz) then --如果表是nil 那么这里要做针对性处理 else --不是nil 就可以遍历 for k,v in pairs(zz) do traceprint(k,"->",v) end end
ipairs 是针对数组 数组就是从1开始的连续的数字索引 pairs就是适合各种情况
123
L1[table]05. 数组长度
#
1.表内的数字索引所以算长度 字符串索引不算在长度内
2 在表元素里面值设置nil 这个影响到表元素长度的计算 而且没有什么准确的规律 所以 表的key和value千万不要成为nil key为nil 会报错 value为nil 不会报错 但是会干扰表长度的计算
结论:#来获取表长度只适合纯数字索引的(并且这个数字索引从1开始)表 要想完整的获取表的长度 可以考虑下面的办法
--功能:获取对应表的长度 --返回值: 返回-1表示当前不是table 大于等于0都是正常的返回(元素内容为nil的不计算在内) function testlib:len(tableName) local result=-1 local i=0--负责计数的 if (tableName) then for v,k in pairs(tableName) do i=i+1 end result=i else --如果为nil 那么 end return result end
L1[table]06. table小数点与中括号取值区别
L1[table]07. 多重嵌套table
小知识:lua表的分隔符的变化和换行声明表写法
test2={10, 20, age=14;--都好也可以换成分号 依然没什么影响 address="山东", --直接换行即可 对声明表没影响 按键还需要加_结尾 这里不用 name="zjl" --最后一行可以加逗号 也可以不加 } for v,k in pairs(test2) do traceprint(v,"--",k) end
123
小知识:一个二重表的基本结构 和 简单的调用
test3={ {id=1,name="zjl",age=14}, {id=2,name="zjl2",age=14}, {id=3,name="zjl3",age=14}, } traceprint(test3[2].name)
123
L1[table]08. 循环遍历数组
小知识:表之间的比较大小和是否相123等
test4={1,2,3} test5={1,2,3} traceprint(test4) traceprint(test5) if (test4==test5) then traceprint("相等") else traceprint("不等") end
结果
test7.lua:74: table: 01351bd0 --test4这个表变量内容是内存地址 他们指向的内存地址明显不同自然不可能相等
test7.lua:75: table: 01351c70 --test5这个表变量内容是内存地址
test7.lua:79: 不等
123
L1[table]09. 循环遍历table
小知识:完美的遍历表 嵌套表也可以完美遍历 转载地址:https://blog.csdn.net/u013577276/article/details/77127204
function dumpTable(t, tab) local str = str or "" if not t then print("table is nil") return str end tab = tab or " " tab = tab .. " " str = str .. "{\n" if type(t) == "table" then for k, v in pairs(t) do if type(k) == "number" then str = str .. string.sub(tab, 2, string.len(tab)) .. "[" .. k .. "]" .. " = " else str = str .. string.sub(tab, 2, string.len(tab)) .. "[\"" .. k .. "\"]" .. " = " end if type(v) == "string" then str = str .. "\"" .. v .. "\"" .. "\n" elseif type(v) == "number" then str = str .. v .. "\n" elseif type(v) == "boolean" then str = str .. tostring(v) .. "\n" elseif type(v) == "function" then str = str .. tostring(v) .. "\n" elseif type(v) == "thread" then str = str .. "thread : " .. tostring(v) .. "\n" elseif type(v) == "userdata" then str = str .. "userdata : " .. tostring(v) .. "\n" elseif type(v) == "table" then str = str .. dumpTable(v, tab) .. "\n" else str = str .. "unknow : " .. tostring(v) .. "\n" end end str = str .. string.sub(tab, 2, string.len(tab) - 1) .. "}" else str = t end return str end --------------------- xx={1,2,3, {id=13,name="zjl"}, {id=14,name="zjl"}, {id=15,name="zjl"}, {tel=1548924786, tel1=3423423423, tel2=1231231, tel3=1231231, {address="山东",age=18,name="dfsdf"} }, "dfsdf", "dfsdfsdfsdfsdfsdf", } print(dumpTable(xx))
疑问:类方法的参数 可以正常传递数值 字符串参数 但是表参数传递进去似乎是nil
找了一会资料 没找到这方面的情况
等之后再研究
--测试用类方法 function testlib:test(tableName) if tableName then --如果参数不为nil 就遍历出表元素 for v,k in pairs(tableName) do print(v,k) end else --为nil 则输出下 print("table is nil") end end
zjl=require("testlib")--导入该类 yyy={1,2,3,4,5,6,7} zjl.traceprint("hello")--输出出hello 表明类方法可以在这个源码里面可以使用 zjl.test(yyy)--结果 table is nil
123
L1[table]10. 三目运算符技巧
小知识:一个变量赋值的小技巧 防止一些变量根本不存在或者说是nil的情况导致代码报错崩溃
举个例子比如tonumber()返回就可能是nil 如果我们用tonumber() 强制转化 默认结果是数字 以默认结果来进行处理
就会代码出错
function test1(a) return tonumber(a)+1 end print(test1("10")) print(test1("sas"))
结果
11
D:\Program Files (x86)\zerobrane\bin\lua53.exe: E:\lua\test10.lua:19: attempt to perform arithmetic on a nil value
如果我们用 a=a or 0 这样的格式 就能从逻辑上避免这样的问题 就算转化失败为nil 我们也可以给他赋一个初值 避免报错
function test1(a) local a=tonumber(a) a=a or 0 --这个就是转化为数值后的结果 如果转化成功 则a还是a 转化失败为nil则a默认为0 --这样不管如何a总会是数值 不会导致报错 return a+1 end print(test1("10")) print(test1("sas"))
老师的演示例子也展示了表变量避免nil的情况
local tempTbale={}--设置一个空表作为一个表的默认值
xTable=xTable or tempTbale --如果xTable是nil 那么就会给赋值一个空表tempTbale
--到这里为止 不管以前xTable 是不是nil 在这都是一个表了
上面的a=a or 0 或者我们后面要学 x?a:b 这种三目运算符 其实 完全可以用一个函数来解释
function iif(expression,A,B) local result if (expression) then result=A else result=B end return result end
L1[table]11. table函数库
1.table.connect()--这个只是针对数组 就是从1开始的连续的数字索引表 其他索引就不操作 而且该函数第二个参数就是分隔符设置 第三个参数是指定从第几个数字索引元素开始 第四个就是合并到哪个数字索引结束 作用是把属于数组的元素全部以某个分隔符一样拼接成字符串
2.table.insert() 还是只针对数组 插入末尾 table.insert(yy,”插入的内容”) 插入指定的数字索引位置 table.insert(yy,2,”插入的内容”)
3 table.remove() 和上面相反 经过测试 删除不存在的数字索引 也不会报错
4 table.sort 排序 而且可以设置排序判断的函数
3 table.move (a1, f, e, t [,a2])
等价操作: a2[t],··· = a1[f],···,a1[e]
结论:建议表尽量都使用数字索引 因为table函数库处理的都是数组类型 表类型更加的复杂
123
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现