lua loadstring传递参数_lua学习之函数篇
函数
- 函数是对语句和表达式进行抽象的主要机制
两种用法
- 一是可以完成特定的任务,一句函数调用被视为一条语句
- 二是以只用来计算并返回特定的结果,视为一句表达式
print("Hello, World")a = math.sin(3) + math.cos(10)print(os.date())
- 无论哪种用法都需要将所有参数放到一对圆括号中
- 但如果参数是字面字符串或 table 构造式的话,可以放在括号中,也可以不放
- 即使在调用函数时没有参数,也必须有一个 () 空括号,如调用 os.date()
print "Hello, World" -- 等价于 print("Hello, World")print {1, 2, 3} -- 等价于 print({1, 2, 3})function add(a) local sum = 0 for i, v in ipairs(a) do sum = sum + v end return sumendb = {1, 2, 3}add(b)
- function 是定义函数的关键字
- add 是函数名
- a 是函数的形式参数,是函数定义式参数列表中的参数
- add(b) 调用这个函数所传入的参数称为实际参数
- 调用函数的实际参数的个数可以与函数定义时的形式参数个数不同
- lua 会自动调整实参的数量,以匹配参数表的要求,这和多s重赋值类似
- 若实参少于形参,多余的形参被初始化为 nil
- 若实参多余形参,多余的实参被抛弃
- lua 程序既可以使用 以 lua 编写的函数,也可使用 C 语言编写的函数
function f(a, b) return a or bendf(3) -- a = 3, b = nilf(3, 4) -- a = 3, b = 4f(3, 4, 5) -- a = 3, b = 4 ,5 被丢弃了
定义一个全局的计数器
function intCount(n) n = n or 1 -- 赋值一个默认值 count = count + 1end
面向对象式调用函数
- o.foo(o, x)
- o:foo(x) 等价于 o.foo(o, x)
- 冒号操作符使得我们在调用 o.foo 时隐含地将 o 作为函数的第一个参数
多重返回值
- lua 允许函数返回多个结果
- 如标准库中的一些预定义函数
-- 用于在字符串中定位一个模式的函数 string.findprint(string.find("Hello Lua users", "Lua")) -- 开始的位置 7, 结束的位置 9
- 在 return 后列出需要返回的所有值即可,用 , 逗号分隔
-- 查找数组中的最大元素,并返回这个元素的所在位置function maximum(a) local mi = 1 -- 最大值的索引 local max = a[mi] -- 最大值 for i,v in ipairs(a) do if v > max then mi = i max = v end end return max, miendmaximum(a) -- 没有任何反应print(maximum({3, 4, 23, 5, 7}) -- 23 3print(maximum({3, 4, 23, 5, 7} .. "a") -- 23a
- 如果将函数调用作为单独的语句执行,lua 会丢弃所有的返回值
- 如果将将函数作为表达式的一部分调用,只保留函数的第一个返回值
- 只有当函数是一系列表达式中的最后一个元素(或只有一个元素的时候),才会获取所有的返回值
一系列表达式在 Lua 中的 4 中情况
- 多重赋值
- 函数调用时传入的实参列表
- table 构造式
- return 语句
多重赋值
- 在多重赋值中,如果一个函数调用是最后(或仅有)的一个表达式,lua 会保留尽可能多的返回值,用来匹配赋值的变量
- 如果一个函数没有返回值或没有返回足够多的返回值,那么 lua 会用 nil 来补充缺失的值
- 如果一个函数调用不是一系列表达式中的最后一个元素,就只能返回一个值
- 如果一个函数调用作为另一个函数调用的最后一个(或仅有的)实参的时候,第一个函数的所有返回值都会作为实参传递给另一个函数
function foo0() endfunction foo1() return "a" endfunction foo2() return "a", "b" end-- 多重赋值的4种情况-- 第一种情况x, y = foo2() -- x = "a" , y = "b"x = foo2() -- x = "a"x, y, z = 10, foo2() -- x = 10, y = "a", z = "b"-- 第二种情况x, y = foo0() -- x = nil, y = nilx, y = foo1() -- x = "a", y = nilx, y, z = foo2() -- x = "a", y = "b", z = nil-- 第三种情况x, y = foo2(), 20 -- x = "a", y = 20x, y = foo0(), 20, 30 -- x = nil, y = 20-- 第四种情况print(foo0()) -- 不会打印任何值print(foo1()) -- aprint(foo2()) -- a, bprint(foo2(), 20) -- a, 1print(foo2() .. "x") -- ax
table 构造式
- table 构造式可以完整地接收一个函数调用的所有结果,即不会有任何数量方面的调整
- 但这种行为,只有当一个函数调用作为最后一个元素时才会发生
- 其他位置上的函数调用总是只产生一个结果值
function foo0() endfunction foo1() return "a" endfunction foo2() return "a", "b" endt = {foo2()} -- t = {"a", "b"}t = {foo2(), "x"} -- t = {"a", "x"}
return
- 将函数调用放入一对圆括号 () 中,使其只返回一个结果
- return 语句后面的内容不需要 () 圆括号
- 如果强行加上则会使一个多返回值的函数,强制其只返回一个 return(f())
function foo0() endfunction foo1() return "a" endfunction foo2() return "a", "b" endfunction foo(i) if i == 0 then return foo0() elseif i == 1 then return foo1() elseif i == 2 then return foo2() endendprint(foo(1)) -- aprint(foo(2)) -- a, bprint(foo(0)) -- 无返回值-- () 包裹print((foo(1)) -- aprint((foo(2)) -- aprint((foo(0)) -- nil 不太懂为什么
unpack 函数
- 接收一个数组作为参数
- 并从下标 1 开始返回该数组的所有元素
- 这个预定义函数由 C 语言编写
print(unpack{10, 20, 30}) -- 10 20 30a, b = unpack{10, 20, 30} -- a = 10, b = 20
- 用于泛型调用
- 泛型调用就是可以以任何实参来调用任何函数
-- 调用任意函数 f, 而所有的参数都在数组 a 中-- unpack 将返回 a 中的所有值,这些值作为 f 的实参f(unpack(a)) f = string.finda = {"hello", "ll"}f(unpack(a)) -- 3 4 等效于 string.find("hello", "ll")
用 lua 递归实现 unpack
function unpack(t, i) i = i or 1 if t[i] then return t[i], unpack(t, i + 1) endend
变长参数
- lua 中的函数可以接收不同数量的实参
- 当这个函数被调用时,它的所有参数都会被收集到一起
- 这部分收集起来的实参称为这个函数的「变长参数」
- ... 3个点表示该函数接收不同数量的实参
- 一个函数要访问它的变长参数时,需要用 ... 三个点,此时 ... 三个点是作为一个表达式使用的
- 表达式 ... 三个点的行为类似一个具有多重返回值的函数,它返回的是当前函数的所有变长参数
- 具有变长参数的函数也可以拥有任意数量的固定参数
- 但固定参数一定要在变长参数之前
- 当变长参数中包含 nil ,则需要用 select 访问变长参数
- 调用 select 时,必须传入一个固定参数 selector(选择开关) 和一系列变长参数
- 如果 selector 为数字 n ,那么 select 返回它的第 n 个可变实参
- 否则,select 只能为字符串 "#" ,这样 select 会返回变长参数的总数,包括 nil
-- 返回所有参数的和function add(...) local s = 0 for i, v in ipairs{...} do -- 表达式{...}表示一个由变长参数构成的数组 s = s + v end return sendprint(add(3, 4, 5, 100)) -- 115-- 调试技巧 ,类似与直接调用函数 foo ,但在调用 foo 前先调用 print 打印其所有的实参function foo1(...) print("calling foo:", ...) return foo(...)end-- 获取函数的实参列表function foo(a, b, c) endfunction foo(...) local a, b, c = ...end-- 格式化文本 string.format ,输出文本 io.write-- 固定参数一定要在变长参数之前function fwrite(fmt, ...) return io.write(string.format(fmt, ...))endfwrite() -- fmt = nilfwrite("a") -- fmt = a fwrite("%d%d", 4, 5) -- fmt = "%d%d" , 变长参数 = 4, 5for i = 1, select('#', ...) do local arg = select('#', ...) end
具名参数
- lua 中的参数传递机制是具有 「位置性」的
- 就是说在调用一个函数时,实参是通过它在参数表中的位置与形参匹配起来的
- 第一个实参的值与第一个形参相匹配,依此类推
- 定义:通过名称来指定实参
- 可将所有的实参组织到一个 table 中,并将这个 table 作为唯一的实参传给函数
- lua 中特殊的函数调用语法,当实参只有一个 table 构造式时,函数调用中的圆括号是可有可无的
os.rename -- 文件改名,希望达到的效果 os.rename(old = "temp.lua", new = "temp1.lua")-- lua 不支持注释的写法rename = {old = "temp.lua", new = "temp1.lua"}function rename (arg) return os.rename(arg.old, arg.new)endx = Window{x = 0, y = 0, width = 300, height = 200, title = "Lua", background = "blue", border = "true"}-- Window 函数根据要求检查必填参数,或为某些函数添加默认值-- 假设 _Window 是真正用于创建新窗口的函数,要求所有参数以正确次序传入function Window(options) if type(options.title) ~= "string" then error("no title") elseif type(options.width) ~= "number" then error("no width") elseif type(options.height) ~= "height" then error("no height") end _Window(options.title, options.x or 0 -- 默认值 options.y or 0 -- 默认值 options.width, options.height, options.background or "white" -- 默认值 options.border -- 默认值为 false(nil) )
lua loadstring传递参数_lua学习之函数篇相关推荐
- redirect通过url_for传递参数_Excel VBA解读 | 进阶篇(127):Sub过程的参数传递技术...
学习Excel技术,关注微信公众号: excelperfect 前面用了几篇文章详细讲解了Sub过程的语法及相关知识,本文进一步讲解与Sub过程相关的一些"重要事项",以进一步理解 ...
- 【python学习】函数篇-初阶
什么是函数? 函数是组织好的,可重复使用的,用来实现单一或相关联功能的代码段,它能够提高应用的模块性和代码的重复利用率. 1 函数的定义和调用 Python定义函数使用def关键字,格式如下: def ...
- 廖雪峰JS学习总结-函数篇
最近在刷廖雪峰的JS教程,把里面的自己不太清楚的东西在刷一遍. 教程网址:www.liaoxuefeng.com/wiki/001434- 函数的定义和调用: 如果没有return语句,函数执行完毕后 ...
- shell 函数传递参数_python3基础之函数参数的传递方式
c++函数传参有三种方式:分别是按值.按引用和按指针传递.简单的说按值传递的方式不会改变传递的参数本身,按引用传递的方式会改变参数本身(当然可以用const限制),按指针传递方式会改变指针指向的对象. ...
- lua mysql 存储类型_Lua学习----Lua基础数据类型
前言 Lua有6中数据类型,分别是nil(空).boolean(布尔).number(数字).string(字符).table(表).function(函数) 在Lua中可以使用type函数来返回一个 ...
- 奇舞学院及高程学习笔记-函数篇
函数 函数声明与函数表达式 函数声明提升与变量声明提升 函数声明:以function开头的函数定义. js在执行代码之前会先读取函数声明和变量声明,函数声明整个提升,变量赋值在执行时再执行. cons ...
- python中def fun 定义函数列表_Python学习之 函数篇
Python函数 函数就是完成特定功能的一个语句组,这组语句可以作为一个单位使用,并且给它取一个名字. 可以通过函数名在程序的不同地方多次执行(这通常叫函数调用). 函数定义要在函数调用之前,否则函数 ...
- 理解ROS服务和参数---ROS学习第6篇
文章目录 1.ROS服务 2.使用rosservice 2.1 rosservice list 2.2 rosservice type 2.3 rosservice call 3. 使用rospara ...
- 以下是一个使用 VBA 的例子,演示了 ByVal 和 ByRef 的区别,以及如何在函数中传递参数和返回值。
以下是一个使用 VBA 的例子,演示了 ByVal 和 ByRef 的区别,以及如何在函数中传递参数和返回值: Sub Example()Dim x As Integer, y As Integerx ...
最新文章
- python下载文件暂停恢复_python下载文件记录黑名单的实现代码
- AndroidSDK下载以及配置
- 【Linux】一步一步学Linux——apt-get命令(278)
- 部署 k8s Cluster(下)- 每天5分钟玩转 Docker 容器技术(119)
- AngularJs ng-repeat限制循环次数
- nedc工况_东南DX3 EV续航升级 NEDC综合工况续航451公里
- MySQL自定义函数(四十六)
- DataSet,DataTable,DateView的关系和用法
- 看完这篇,轻松解决FastReport合并单元格!
- 关于Qt作为第三方库,QGIS二次开发作为第三方库,Qt ui编译的一些问题
- HDFS的读写流程步骤(附图文解析)
- 计算机启动时为啥总要检测硬盘,每次开机都磁盘检查怎么办_如何关闭硬盘开机自检-win7之家...
- android局部布局刷新,Android RecyclerView 局部刷新分析
- android向DDR读写数据,透过数据看本质 - 被“吹爆”的LPDDR5内存究竟有多强大?...
- 字符串全排列与组合算法以及八皇后问题
- ug如何复制面_UG复制面,移动面,删除面,镜像面,替换面,阵列面命令用法与作用...
- dagum基尼系数分析全流程
- 谈谈什么是数据质量管理
- The Little Book of Mindfulness by Gilly Pickup
- .net 文字转语音简单应用 SpeedSynthesis,部署IIS
热门文章
- .net core上 K8S(七).netcore程序的服务发现
- 领域驱动设计,让程序员心中有码(二)
- ASP.NET Core中为指定类添加WebApi服务功能
- Jexus针对Asp.net core应用程序的六大不可替代的优势
- ZKWeb网站框架的动态编译的实现原理
- 在微信小程序中使用“随机键盘”
- 学妹,你要的C语言版AOE网络数据结构来了,就这么简单!
- 【经典回放】多种语言系列数据结构算法:队列(C版)
- JavaScript三种弹出框(alert,confirm和prompt)用法举例
- NDVI最大值法MVC合成之ArcGIS Cell Statistics 实现