【小白学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 ...
随机推荐
- HTTP各个status code是什么意思【已解决】
在介绍状态码之前,要简单讲一下为什么要有状态码这个东西.计算机之间的通信以协议为共同基础,客户端和服务端都按照协议的约定进行通信.HTTP的状态码就在HTTP的协议内,规定了很多的状态.客户端请求服务 ...
- [转载]——说说IO
本文转载自"和你在一起"的"说说IO"系列文章https://pengjiaheng.iteye.com/,总共分为8篇,特意整理.收录在此,支持原创.尊重原创 ...
- Django-0-环境搭建、创建项目、启动服务
1- 创建虚拟环境名称(在虚拟机中) mkvirtualenv -p /usr/bin/python3 envname (/usr/bin/python3 - 你自己在虚拟机中的Python解释器 ...
- js 倒计时跳转
用js实现简单的倒计时结束页面跳转效果,主要用到setInterval()和clearInterval()方法,页面跳转使用window.location.href = " ".倒 ...
- 安装composer时,提示 /usr/bin/env: php: 没有那个文件或目录
今晚在Ubuntu环境上安装composer后,想查看下是否安装成功,使用composer -v,结果提示:/usr/bin/env: php: 没有那个文件或目录 现说说我的解决办法: 它提示的原因 ...
- mstsc远程连接发生身份验证错误要求的函数不受支持
在win7电脑上使用远程连接连接一台服务器时,出现发生身份验证错误要求的函数不受支持的错误,原因是本地组策略配置错误,如下图: 解决办法: 进入windows命令行模式输入命令: 会弹出本地策略组编辑 ...
- 解决FileZilla访问手机ftp服务只能删除浏览文件不能下载文件的问题
用了Linux系统之后,很多资源都不方便获取, 因为很多资料都是放在百某某盘上面. 无意中看到我手机有FTP服务,想到我电脑装有FileZilla,可以访问手机了 然后就连接上了. 但是浏览的时候发现 ...
- 【shell实例】定时21:00-21:05,循环调用DSQL脚本,其它时段自动退出
1.功能描述: 每日21:00定时调起test.sh,循环调起DSQL脚本test.dsql,直到21:05程序自动退出,捕获日志到相应log文件中. 2.日志文件: (1)日期.log文件中含Err ...
- zookeeper 分布式锁原理
zookeeper 分布式锁原理: 1 大家也许都很熟悉了多个线程或者多个进程间的共享锁的实现方式了,但是在分布式场景中我们会面临多个Server之间的锁的问题,实现的复杂度比较高.利用基于googl ...
- Apache Jakarta Commons 工具集简介
Apache Jakarta Commons 工具集简介[转] Apache Commons包含了很多开源的工具,用于解决平时编程经常会遇到的问题,减少重复劳动.我选了一些比较常用的项目做简单介绍.文 ...