Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Lua学习笔记:Lua里table表的使用例及介绍

Lua学习笔记:Lua里table表的使用例及介绍

原创
作者头像
晨星成焰
发布于 2024-09-08 03:01:37
发布于 2024-09-08 03:01:37
95900
代码可运行
举报
运行总次数:0
代码可运行

Lua Table 简介

  • Table 结构:在Lua中,table是一种可以存储键值对的数据结构,它既可以用作数组(通过数字索引来访问元素),也可以用作字典(通过任意类型作为键),作为二者的结合体使用也是可以的
  • 索引:除了 nil 和 NaN 外,任何Lua值都可以作为table的索引。
  • 动态调整大小:table没有固定的大小限制,你可以根据需要添加或删除元素。
  • 内存管理:由于Lua的垃圾收集机制,当没有任何引用指向table时,它将被自动回收。 相应的代码Lua层面构造表的使用

CPP的基本调用Lua脚本代码

代码语言:cpp
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <lua.hpp>

int mian()
{
	lua_State* L = luaL_newstate();

	luaL_openlibs(L);

	luaL_dofile(L, "LuaTableTest.lua");

	lua_close(L);
	return 0;
}

表是Lua特有的功能强大的东西。

在Lua脚本中,可以使用 {} 来创建一个空表,并通过直接赋值的方式来初始化数组或字典。例如,通过 myTablekey = value 的形式,可以向表中添加元素。

1.Lua构造表使用例

代码语言:lua
AI代码解释
复制
-- LuaTableTest.lua
-- 创建一个空表
local myTable = {}

-- 作为数组使用
myTable[1] = "Hello"
myTable[2] = "World"

-- 作为字典使用
myTable.name = "Alice"
myTable.age = 25

-- 遍历table
for k, v in pairs(myTable) do
    print(k, v)
end

-- 输出: 输出顺序是随机的,因为TableTable的遍历顺序是随机的
-- 1 Hello
-- 2 World
-- name Alice
-- age 25

2.Lua表库函数使用例

Lua提供了一组丰富的内置函数来帮助操作table,比如table.concat用于连接表中的元素为一个字符串,table.insert用于在指定位置插入新的元素,table.move用于移动表中的元素,table.remove用于移除元素等。

另外,无论何时,若一个操作需要取表的长度,这张表必须是一个真序列,或是拥有 __len 元方法。所有的库函数都忽略传入参数的那张表中的非数字键。

1.链接.插入.移动.移除演示

  • table.concat (list , sep , i , j)
    • list:表
    • sep:分隔符,默认值是空串
    • i:起始索引,默认为1
    • j:结束索引,默认为#list

提供一个列表,其所有元素都是字符串或数字,

返回指定表中从start位置到end位置且每个元素以特定分隔符分割的字符串

注意:当使用 table.concat 函数时,它默认会按照数值索引的顺序连接表中的元素,忽略非数值索引的键值对。

  • table.insert (list, pos, value)
    • list: 表
    • pos: 位置(Lua的索引是从1开始的)
    • value: 值

在 list 的位置 pos 处插入元素 value , 并后移元素 listpos, listpos+1, ···, list#list 。 pos 的默认值为#list+1既数组末尾 , 因此调用 table.insert(t,x) 会将 x 插在列表 t 的末尾。

  • table.move (a1, f, e, t ,a2)
    • a1: 源表
    • f: 开始索引
    • e: 结束索引
    • t: 目标索引
    • a2: 目标表,默认为a1

将开始索引到结束索引区间内的元素从表 a1 移动到表 a2目标索引开始的位置。

目标区间可以和源区间重叠。 索引 f 必须是正数。

  • table.remove (list , pos)
    • list: 表
    • pos: 位置,默认为#list

移除 list 中 pos 位置上的元素,并返回这个被移除的值。 当 pos 是在 1 到 #list 之间的整数时, 它向前移动元素 listpos+1, listpos+2, ···, list#list 并删除元素 list#list; 索引 pos 可以是 #list + 1 ,或在 #list 为 0 时可以是 0 ; 在这些情况下,函数删除元素 listpos。

代码语言:lua
AI代码解释
复制
-- LuaTableFunc.lua
local src = {a=1, b=2,'a', 'b', 'c', 'd'}
-- 数值索引:1='a', 2='b', 3='c'
-- 字符串键:'a'=1, 'b'=2  a=1和b=2是非数字键索引被忽略了
-- concat
print('-------------concat------------')
print(table.concat(src, ','))    -- 输出: a,b,c,d --忽略了a=1,b=2的值
print(table.concat(src, '|',1,3)) -- 输出: a|b|c
table.insert(src, 2, 'x') -- 在2的位置插入x
print(table.concat(src, '#')) -- 输出:a#x#b#c#d

-- insert
print('-------------insert------------')
local insertTest = {1, 2, 3}
table.insert(insertTest, 1, 'a') -- 在1的位置插入a
print(table.concat(insertTest, ','))      -- 输出: a,1,2,3

-- move
print('-------------move------------')
local moveTest = {}
table.move(src, 1, 3, 1, moveTest)
print(table.concat(moveTest, '|'))    -- 输出: a|x|b

-- remove
print('----------------remove-----------')
local removeTest = {1, 2, 3}
print('remove:'..table.remove(removeTest)) -- remove:3
print(table.concat(removeTest, ',')) -- 输出 1,2
table.insert(removeTest,'3') -- 在末尾插入3
print(table.concat(removeTest, '|')) -- 输出 1|2|3

2.sort和pack跟unpack函数示例

  • table.sort (list , comp)
    • list: 表
    • comp: 比较函数,默认使用 <

可以类比于cpp里的sort库函数

注意:当内容中既有number类型又有string类型的元素时,无法进行排序。

在表内从 list1 到 list#list 原地 对其间元素按指定次序排序。 如果提供了 comp , 它必须是一个可以接收两个列表内元素为参数的函数。 当第一个元素需要排在第二个元素之前时,返回真 (因此 not comp(listi+1,listi) 在排序结束后将为真)。 如果没有提供 comp, 将使用标准 Lua 操作 < 作为替代品。

  • table.pack (···) 返回用所有参数以键 1,2, 等填充的新表, 并将 "n" 这个域设为参数的总数。 注意这张返回的表不一定是一个序列。
  • table.unpack (list , i , j)
    • list: 表
    • i: 起始索引,默认为1
    • j: 结束索引,默认为#list

返回列表中的元素。 这个函数等价于return listi, listi+1, ···, listj

i 默认为 1 ,j 默认为 #list。

代码语言:lua
AI代码解释
复制
-- LuaTableFunc.lua

-- sort
print('-------------sort------------')
local sortTest = {'b', 'a', 'c', 'd'}
table.sort(sortTest)
for i,v in ipairs(sortTest) do
    print(i,v)
end
-- 输出 
-- 1	a
-- 2	b
-- 3	c
-- 4	d

-- pack And unpack
print('-------------pack--unpack---------')
local packTest = table.pack(4, 3, 2, 1)
print(packTest.n)      -- 输出: 4 -- n是数组的长度
print(table.unpack(packTest))   -- 输出: 4 3 2 1

print(table.unpack(packTest, 2, 3))     -- 输出: 3 2

C/C++层面构造表的使用

在C/C++中,通过Lua API可以创建和操作Lua表。例如,可以使用lua_newtable来创建一个新的空表,并使用lua_pushstring和lua_setfield来设置表中的键值对。此外,还可以通过lua_setglobal将表设置为全局变量,以便在Lua脚本中访问。之后,通过加载并执行Lua脚本来处理这些表。

1.CPP层面代码

代码语言:cpp
代码运行次数:0
运行
AI代码解释
复制
// lua_pop(L,弹出栈顶元素数量1开始 );

#include <stdio.h>
#include <lua.hpp>

int main()
{
	// 创建一个虚拟机
	lua_State* L = luaL_newstate();

	// 加载一些常用的系统库
	luaL_openlibs(L);

	/*------创造一个表,并设置键值对------ */
	lua_newtable(L); // 创建一个新的 Lua 表,并将其压入栈顶。

	lua_pushstring(L, "xmr"); // 将字符串 "xmr" 压入栈顶。
	lua_setfield(L, 1, "name"); // 将栈顶的值设置为表中键 "name" 对应的值。
	// 此时栈顶的值是 "xmr",而索引 1/-2 指向的是刚创建的表,因此相当于为表添加了一个键 "name" 和对应的值 "xmr"。

	lua_pushstring(L, "Hello World"); // 将字符串 "Hello World" 压入栈顶。
	lua_rawseti(L, -2, 1); // 将栈顶的值设置为表中索引 1 对应的值。
	// 这里使用 `-2`/用1也可以,一般建议用-2 是为了获取表的索引(即上一步创建的表),然后设置索引 1 的值为 "Hello World"。

	lua_setglobal(L, "tab"); // 将当前创建的表设置为全局变量 "tab"。
	// 此时栈顶的值是刚创建的表,该表有两个元素:`name = "xmr"` 和 `[1] = "Hello World"`。

	/*--------------------------------*/

	// 加载 Lua 文件并执行,文件名为 "luaTableTest.lua"
	if (luaL_dofile(L, "CTestLuaTable.lua"))
	{
		// 如果 Lua 文件执行失败,则 Lua 错误会被压入栈顶。
		printf("%s\n", lua_tostring(L, -1)); // 输出错误信息。
	}

	// 关闭虚拟机
	lua_close(L);
	return 0;
}

//代码流程总结
//创建 Lua 虚拟机:使用 luaL_newstate() 创建一个新的 Lua 虚拟机实例。
//加载 Lua 标准库:使用 luaL_openlibs() 加载 Lua 标准库。
//创建 Lua 表:
//使用 lua_newtable() 创建一个新的空表,并将其压入栈顶。
//使用 lua_pushstring() 和 lua_setfield() 设置表中键 "name" 的值为 "xmr"。
//使用 lua_pushstring() 和 lua_rawseti() 设置表中索引 1 的值为 "Hello World"。
//设置全局变量:使用 lua_setglobal() 将创建的表设置为全局变量 "tab"。
//执行 Lua 脚本:使用 luaL_dofile() 加载并执行 Lua 脚本 "luaTableTest.lua"。
//输出结果:脚本执行后,输出表 "tab" 中键 "name" 和索引 1 对应的值。
//关闭虚拟机:使用 lua_close() 关闭 Lua 虚拟机。

2.Lua接收到CPP传过来的表使用例

在Lua脚本中,可以简单地通过全局变量名来访问由C/C++创建并设置的表,例如print(tab.name)和print(tab1),分别输出表tab中键name和索引1对应的值。

代码语言:lua
AI代码解释
复制
-- CTestLuaTable.lua
print(tab.name)  -- 输出表 "tab" 中键 "name" 对应的值。
print(tab[1])    -- 输出表 "tab" 中索引 1 对应的值。

总结

在Lua中,table是一种非常灵活且强大的数据结构,它可以用来存储键值对,既可以作为数组使用(通过数字索引来访问元素),也可以作为字典使用(通过任意类型作为键)。这种灵活性使得table成为了Lua中处理数据的主要工具之一。table没有固定的大小限制,可以根据需要动态地添加或删除元素,并且由于Lua的自动垃圾回收机制,当没有任何引用指向一个table时,它将被自动回收,从而有效地管理内存。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Lua学习笔记:实现一个Lua Class生成器
Lua 中的每个值都可以有一个 元表。 这个 元表 就是一个普通的 Lua 表, 它用于定义原始值在特定操作下的行为。 如果你想改变一个值在特定操作下的行为,你可以在它的元表中设置对应域。 例如,当你对非数字值做加操作时, Lua 会检查该值的元表中的 "__add" 域下的函数。 如果能找到,Lua 则调用这个函数来完成加这个操作。
晨星成焰
2024/09/12
2120
Lua学习笔记:实现一个Lua Class生成器
Lua学习笔记:C/C++中调用Lua函数示例
在学习了Lua中调用C/C++ 函数后,不免令人好奇,是否可以在Lua中定义一些函数来让C/C++来调用?我们甚至可以封装了C/C++的函数库供Lua模块化加载后再传递给需要的C/C++项目调用
晨星成焰
2024/09/11
4340
Lua学习笔记:C/C++中调用Lua函数示例
Lua 5.1 参考手册
Lua 是一个扩展式程序设计语言,它被设计成支持通用的过程式编程,并有相关数据描述的设施。 Lua 也能对面向对象编程,函数式编程,数据驱动式编程提供很好的支持。 它可以作为一个强大、轻量的脚本语言,供任何需要的程序使用。 Lua 以一个用 clean C 写成的库形式提供。(所谓 Clean C ,指的 ANSI C 和 C++ 中共通的一个子集)
sunsky
2020/08/20
4.2K0
Lua学习笔记:Lua里metatable元表的使用
在这个例子中,当我们尝试向 readonlyTable 添加一个新键或更新一个已存在的键时,Lua 会调用元表中的 __newindex 方法。由于我们定义了这个方法来抛出一个错误,因此任何对 readonlyTable 的修改都会失败,并抛出一个错误信息。
晨星成焰
2024/09/09
3230
Lua学习笔记:Lua里metatable元表的使用
自学成菜-流水账学习法lua入门
为表添加操作符 文档页面: http://www.runoob.com/lua/lua-metatables.html
用户2825413
2019/07/15
1.1K0
Lua 中的常用API
luaL_newstate lua_State *luaL_newstate (void); 创建一个新的state luaL_openlibs void luaL_openlibs (lua_State *L); 打开所有的标准lua库到指定状态,也就是把所有标准类库加载到指定的虚拟机. luaL_loadfile int luaL_loadfile (lua_State *L, const char *filename); 加载文件的时候把它当一个lua模块 luaL_dofile和luaL
程序手艺人
2019/02/21
1.9K0
lua 和 cpp 互调
例子中涉及为 lua 编写 so,(lua require 加载) 需要修改 lua/src 下的makefile cppflag 加 -FPIC, 这样后续链接so才不会报错
orientlu
2018/12/24
9660
Lua学习笔记
--Lua笔记-- --0.Lua开篇-- --http://www.cnblogs.com/stephen-liu74/archive/2012/06/11/2403210.html-- --1.Lua基础知识-- --[[ 通过dofile()方法引用其他Lua文件中的函数 在Lua中全局变量不需要声明,直接赋值即可。如果直接访问未初始化的全局变量,Lua也不会报错,直接返回nil。如果不想再使用该全局变量,可直接将其置为nil。 命令行用法如下: lua [options] [lua-scr
_gongluck
2018/03/08
3.2K0
Lua和C如何交互(二)
上一篇文章描述了Lua和C交互的原理, 这篇文章主要通过Demo程序加深Lua和C的交互. 涉及到交互,分为:
程序手艺人
2019/02/21
1.4K0
OpenResty学习指南(二)
对于序列,用table.getn 或者一元操作符 # ,就可以正确返回元素的个数。
luozhiyun
2020/02/18
1.2K0
OpenResty学习指南(二)
亿级流量多级缓存 - Lua整合Redis/Nginx
Lua 是由巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组于1993年开发的一种轻量、小巧的脚本语言,用标准 C 语言编写,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
Parker
2020/07/21
1.4K0
C++与lua的结合,LuaBridge的使用
LuaBridge 是一个简单好用的轻量级且无依赖的库,用于在C ++和 LUA(一种强大,快速,轻量级,可嵌入的脚本语言)之间来回映射数据,函数和类。
杨永贞
2022/05/11
1.8K0
C++与lua的结合,LuaBridge的使用
【游戏开发】小白学Lua——从Lua查找表元素的过程看元表、元方法
在上篇博客中,我们简单地学习了一下Lua的基本语法。其实在Lua中有一个还有一个叫元表的概念,不得不着重地探讨一下。元表在实际地开发中,也是会被极大程度地所使用到。本篇博客,就让我们从Lua查找表元素的过程,来探讨学习一下Lua中的元表。
马三小伙儿
2018/09/12
2K0
Lua
Yolo-Yolo
2024/12/07
2220
Lua
CMake编译和链接Luajit的步骤
参考:https://blog.csdn.net/shun_fzll/article/details/39120965
周星星9527
2021/04/12
1.9K0
Lua与C语言接口编程实战指南:打造高性能、灵活的程序
Lua/c接口编程是skynet的核心技能开发,主要涉及到Lua调C语言和C语言调用Lua的工作流程。从而开发属于自己的组件。
Lion 莱恩呀
2025/07/15
760
Lua与C语言接口编程实战指南:打造高性能、灵活的程序
管中窥豹看Lua
我们的项目使用Unreal开发, 项目内内嵌了UnLua. 某天, DS发生了coredump, 堆栈顶层的几个frame, 都落在了Lua的源代码中. 在定位这个coredump的过程中, 我对Lua部分源代码进行了一些研究. 结合案例, 将这部分学习成果做一个输出, 希望帮助到使用Lua, 以及UnLua的同学.
JohnYao
2022/10/05
7740
管中窥豹看Lua
C语言调用lua
在使用C语言调用luajit之前,我们需要先了解一些必要的概念。首先,我们需要掌握一些基本的lua函数调用的方法。例如,我们可以使用luaL_newstate函数来创建一个新的lua_State结构体,这个结构体是在C语言和Lua之间进行通信的桥梁。同时,我们也需要掌握luaL_openlibs函数,它可以打开Lua的标准库,以便我们可以在C语言中使用Lua的函数。
fensnote
2023/11/07
6040
C语言调用lua
相关推荐
Lua学习笔记:实现一个Lua Class生成器
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验