【小白学Lua】之Lua变长参数和unpack函数
一、简介
Lua的变长参数和unpack函数在实际的开发中应用的还挺多的,比如在设计print函数的时候,需要支持对多个变量进行打印输出,这时我们就需要用到Lua中的变长参数和unpack函数了。
二、Lua变长参数与unpack函数
Lua中支持可变参数,用 ... 表示。比如定义下面的这样一个函数:
local function func1(...)
end
当然它也支持在变长参数前面添加固定参数:
local function func1(var,...)
--dosomething
end
我们在使用变长参数的时候,首先需要将其获取,然后再使用,代码如下:
local function func(...)
local args = { ... } --这里的...和{}符号中间需要有空格号,否则会出错
print (#args)
end func(,,"string",,)
可以发现将变长参数用花括号进行打包以后,会得到一个table,之后就跟我们平时应用Lua没什么区别了。接着我们再来看看unpack函数,在Lua里面我们通常使用它来将数组形式的table拆开。这个函数有三个参数,第一个参数就是要拆的table,第二个参数是起始元素的下标,默认为1,第三个参数是结束元素的下标,默认为table的长度。函数原型如下:

举个栗子,看看如何使用,由于其特性,unpack还可以作为尾调用来提供多个返回值:
local info={,,,,,}
local a,b,c,d,e,f = unpack(info)
print(a,b,c,d,e,f)
--输出结果:1 2 3 4 5 6
local function func1 (t)
return unpack(t)
end
local v1,v2,v3,v4,v5,v6 = func1(info)
print(v1,v2,v3,v4,v5,v6)
需要注意的一点是,如果遇到数组下有nil,或者有字母key的时候,unpack将会返回nil,代码如下:
local info={,,,nil,,p=}
local a,b,c,d,e,f=unpack(info)
print(a,b,c,d,e,f)
输出结果: nil nil
三、小实例---拓展print函数
我们都知道在lua中可以用print函数进行打印操作,它本身也支持传递变长参数,不过美中不足的就是它不支持打印table中的内容,比如下面的这段代码:
print(,,,{,})
运行上面的这段代码,你通常会得到类似下面的这种输出:
table: 00FE9950
可以看到table中的元素没有被一一打印出来,因此我们可以利用lua的变长参数的功能来对print进行拓展,使他支持打印table中元素的内容:
local raw_print = print local function printTable(t)
if type(t) == "table" then
for _,v in pairs(t) do
if type(v) == "table" then
printTable(v)
else
raw_print(v)
end
end
end
end local function printExt(...)
local args = { ... }
for _,v in pairs(args) do
if type(v) == "table" then
printTable(v)
else
raw_print(v)
end
end
end rawset(_G,"print",printExt) print(,,,{,,{"abc"},nil})
简单说一下原理吧,先用局部变量将lua原始的print函数保存下来备用。然后分别定义printTable和printExt函数。printTable使用递归的方式对表中的元素进行遍历及打印。printExt会遍历外部传进来的多参数,然后根据类型进行分别处理。最后将全局环境中的原生print函数覆盖为我们自定义的printExt。运行效果如下:
abc
四、总结
在本篇博客中,马三同大家一起了解了Lua中变长参数和unpack函数的使用,并且通过拓展原生print函数的实例进行了练习。
如果觉得本篇博客对您有帮助,可以扫码小小地鼓励下马三,马三会写出更多的好文章,支持微信和支付宝哟!

作者:马三小伙儿
出处:https://www.cnblogs.com/msxh/p/10054070.html
请尊重别人的劳动成果,让分享成为一种美德,欢迎转载。另外,文章在表述和代码方面如有不妥之处,欢迎批评指正。留下你的脚印,欢迎评论!
【小白学Lua】之Lua变长参数和unpack函数的更多相关文章
- C++中的变长参数
新参与的项目中,为了使用共享内存和自定义内存池,我们自己定义了MemNew函数,且在函数内部对于非pod类型自动执行构造函数.在需要的地方调用自定义的MemNew函数.这样就带来一个问题,使用stl的 ...
- Lua 变长参数(variable number of arguments)
lua变长参数 function add ( ... ) for i, v in ipairs{...} do print(i, ' ', v) end end add(1, 2, 'sdf') lu ...
- (一)预定义宏、__func__、_Pragma、变长参数宏定义以及__VA_ARGS__
作为第一篇,首先要说一下C++11与C99的兼容性. C++11将 对以下这些C99特性的支持 都纳入新标准中: 1) C99中的预定义宏 2) __func__预定义标识符 3) _Pragma操作 ...
- Scala 变长参数
如果Scala定义变长参数 def sum(i Int*), 那么调用sum时,可以直接输入sum(1,2,3,4,5) 但是不可以sum(1 to 5) 必须要将1 to 5 强制为seq sum( ...
- 《OOC》笔记(3)——C语言变长参数va_list的用法
<OOC>笔记(3)——C语言变长参数va_list的用法 C语言中赫赫有名的printf函数,能够接受的参数数目不固定,这就是变长参数.C#里也有params这个关键字用来实现变长参数. ...
- C++11变长参数模板
[C++11变长参数模板] C++03只有固定模板参数.C++11 加入新的表示法,允许任意个数.任意类别的模板参数,不必在定义时将参数的个数固定. 实参的个数也可以是 0,所以 tuple<& ...
- 【Unix环境高级编程】编写变长参数函数
文件的格式输入输出函数都支持变长参数.定义时,变长参数列表通过省略号'...'表示, 因此函数定义格式为: type 函数名(parm1, parm2,parmN,...); Unix的变长参数通过v ...
- java常量和变量的定义规则,变长参数的使用
首先是定义的一般规则,类名首字母全部大写,常量全部大写用下划线分隔,变量用驼峰形式.注意使用long赋值用L时不能写小写的L要写大写的,不然会和数字“1”傻傻分不清. 下面是举例: public cl ...
- Java基础12-工具类;变长参数;IO
作业解析 取出整数的16进制表示形式 \u00ff /** * int2hex * */ public static String int2hex(int i) { String str = &quo ...
随机推荐
- DataPipeline创始人&CEO 陈诚:沃森与AI
引言:本文来自infoQ架构师电子月刊对DataPipeline创始人&CEO陈诚的约稿.陈诚,毕业于上海交大,留学于美国密西根大学,前Yelp大数据研发工程师,曾就职于美国Google.Ye ...
- 数据库原理 - 序列7 - Binlog与主从复制
本文节选自作者书籍<软件架构设计:大型网站技术架构与业务架构融合之道>.作者微信公众号:架构之道与术.公众号底部菜单有书友群可以加入,与作者和其他读者进行深入讨论.也可以在京东.天猫上购买 ...
- 如何在FineUIMvc(ASP.NET MVC)视图中绑定多个模型?
起因 这是知识星球内的一个网友提出的,按理说ASP.NET MVC中一个视图只能绑定一个模型(Model),在视图顶部标识如下: @model IEnumerable<FineUICore.Ex ...
- 随心测试_软测基础_007<软测学习路线建议>
如果你对软测感兴趣,那么如何学习软件测试呢? 贴心小提示:以下内容,仅供参考,不挖坑 1:学习方式_职业教育选择观 ————SX的观点:成本 | 收益说,理性接受 软测产业服务链中,测试工程师重在于& ...
- 11 Django REST Framework 针对基于类的视图添加 @csrf_exempt
01-在类的 dispatch 方法上使用 @csrf_exempt from django.views.decorators.csrf import csrf_exempt class MyView ...
- MySQL大小写敏感
MySQL大小写敏感说明 - TonyWu - 博客园https://www.cnblogs.com/wzmenjoy/p/4244545.html
- C# NetStream
标题:NetStream 关注点:Read.Write 正文: int size = Read(buf, 0, buf.length); 这里一次会读入length个字节,如果小于这个数量,后面的就是 ...
- Netty 客户端断线重连
client 关闭后会执行 finally 代码块,可以在这里可以进行重连操作 public class NettyClient implements Runnable { private final ...
- ios端阻止页面滚动露底
转自 http://www.eboy.me/archives/129: 在IOS端的微信中使用H5页面,页面滑动到底部时,再向上拉或页面在顶部时下拉,总会露出微信自带的底色:总是会让人不爽. 以下是一 ...
- Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3) D. Barcelonian Distance 几何代数(简单)
题意:给出一条直线 ax +by+c=0 给出两个整点 (x1,y1) (x2,y2) 只有在x,y坐标至少有一个整点的时 以及 给出的直线才有路径(也就是格子坐标图的线上) 问 两个整点所需要 ...