函数

  1. 函数是对语句和表达式进行抽象的主要机制

两种用法

  1. 一是可以完成特定的任务,一句函数调用被视为一条语句
  2. 二是以只用来计算并返回特定的结果,视为一句表达式
print("Hello, World")a = math.sin(3) + math.cos(10)print(os.date())​
  1. 无论哪种用法都需要将所有参数放到一对圆括号中
  2. 但如果参数是字面字符串或 table 构造式的话,可以放在括号中,也可以不放
  3. 即使在调用函数时没有参数,也必须有一个 () 空括号,如调用 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)
  1. function 是定义函数的关键字
  2. add 是函数名
  3. a 是函数的形式参数,是函数定义式参数列表中的参数
  4. add(b) 调用这个函数所传入的参数称为实际参数
  5. 调用函数的实际参数的个数可以与函数定义时的形式参数个数不同
  6. lua 会自动调整实参的数量,以匹配参数表的要求,这和多s重赋值类似
  7. 若实参少于形参,多余的形参被初始化为 nil
  8. 若实参多余形参,多余的实参被抛弃
  9. 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

面向对象式调用函数

  1. o.foo(o, x)
  2. o:foo(x) 等价于 o.foo(o, x)
  3. 冒号操作符使得我们在调用 o.foo 时隐含地将 o 作为函数的第一个参数

多重返回值

  1. lua 允许函数返回多个结果
  2. 如标准库中的一些预定义函数
-- 用于在字符串中定位一个模式的函数 string.findprint(string.find("Hello Lua users", "Lua")) -- 开始的位置 7, 结束的位置 9
  1. 在 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
  1. 如果将函数调用作为单独的语句执行,lua 会丢弃所有的返回值
  2. 如果将将函数作为表达式的一部分调用,只保留函数的第一个返回值
  3. 只有当函数是一系列表达式中的最后一个元素(或只有一个元素的时候),才会获取所有的返回值

一系列表达式在 Lua 中的 4 中情况

  1. 多重赋值
  2. 函数调用时传入的实参列表
  3. table 构造式
  4. return 语句

多重赋值

  1. 在多重赋值中,如果一个函数调用是最后(或仅有)的一个表达式,lua 会保留尽可能多的返回值,用来匹配赋值的变量
  2. 如果一个函数没有返回值或没有返回足够多的返回值,那么 lua 会用 nil 来补充缺失的值
  3. 如果一个函数调用不是一系列表达式中的最后一个元素,就只能返回一个值
  4. 如果一个函数调用作为另一个函数调用的最后一个(或仅有的)实参的时候,第一个函数的所有返回值都会作为实参传递给另一个函数
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 构造式

  1. table 构造式可以完整地接收一个函数调用的所有结果,即不会有任何数量方面的调整
  2. 但这种行为,只有当一个函数调用作为最后一个元素时才会发生
  3. 其他位置上的函数调用总是只产生一个结果值
function foo0() endfunction foo1() return "a" endfunction foo2() return "a", "b" endt = {foo2()} -- t = {"a", "b"}t = {foo2(), "x"} -- t = {"a", "x"}​

return

  1. 将函数调用放入一对圆括号 () 中,使其只返回一个结果
  2. return 语句后面的内容不需要 () 圆括号
  3. 如果强行加上则会使一个多返回值的函数,强制其只返回一个 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. 接收一个数组作为参数
  2. 并从下标 1 开始返回该数组的所有元素
  3. 这个预定义函数由 C 语言编写
print(unpack{10, 20, 30}) -- 10 20 30a, b = unpack{10, 20, 30}  -- a = 10, b = 20
  1. 用于泛型调用
  2. 泛型调用就是可以以任何实参来调用任何函数
-- 调用任意函数 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

变长参数

  1. lua 中的函数可以接收不同数量的实参
  2. 当这个函数被调用时,它的所有参数都会被收集到一起
  3. 这部分收集起来的实参称为这个函数的「变长参数」
  4. ... 3个点表示该函数接收不同数量的实参
  5. 一个函数要访问它的变长参数时,需要用 ... 三个点,此时 ... 三个点是作为一个表达式使用的
  6. 表达式 ... 三个点的行为类似一个具有多重返回值的函数,它返回的是当前函数的所有变长参数
  7. 具有变长参数的函数也可以拥有任意数量的固定参数
  8. 但固定参数一定要在变长参数之前
  9. 当变长参数中包含 nil ,则需要用 select 访问变长参数
  10. 调用 select 时,必须传入一个固定参数 selector(选择开关) 和一系列变长参数
  11. 如果 selector 为数字 n ,那么 select 返回它的第 n 个可变实参
  12. 否则,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, 5​for i = 1, select('#', ...) do    local arg = select('#', ...)    end

具名参数

  1. lua 中的参数传递机制是具有 「位置性」的
  2. 就是说在调用一个函数时,实参是通过它在参数表中的位置与形参匹配起来的
  3. 第一个实参的值与第一个形参相匹配,依此类推
  4. 定义:通过名称来指定实参
  5. 可将所有的实参组织到一个 table 中,并将这个 table 作为唯一的实参传给函数
  6. 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)end​x = 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学习之函数篇相关推荐

  1. redirect通过url_for传递参数_Excel VBA解读 | 进阶篇(127):Sub过程的参数传递技术...

    学习Excel技术,关注微信公众号: excelperfect 前面用了几篇文章详细讲解了Sub过程的语法及相关知识,本文进一步讲解与Sub过程相关的一些"重要事项",以进一步理解 ...

  2. 【python学习】函数篇-初阶

    什么是函数? 函数是组织好的,可重复使用的,用来实现单一或相关联功能的代码段,它能够提高应用的模块性和代码的重复利用率. 1 函数的定义和调用 Python定义函数使用def关键字,格式如下: def ...

  3. 廖雪峰JS学习总结-函数篇

    最近在刷廖雪峰的JS教程,把里面的自己不太清楚的东西在刷一遍. 教程网址:www.liaoxuefeng.com/wiki/001434- 函数的定义和调用: 如果没有return语句,函数执行完毕后 ...

  4. shell 函数传递参数_python3基础之函数参数的传递方式

    c++函数传参有三种方式:分别是按值.按引用和按指针传递.简单的说按值传递的方式不会改变传递的参数本身,按引用传递的方式会改变参数本身(当然可以用const限制),按指针传递方式会改变指针指向的对象. ...

  5. lua mysql 存储类型_Lua学习----Lua基础数据类型

    前言 Lua有6中数据类型,分别是nil(空).boolean(布尔).number(数字).string(字符).table(表).function(函数) 在Lua中可以使用type函数来返回一个 ...

  6. 奇舞学院及高程学习笔记-函数篇

    函数 函数声明与函数表达式 函数声明提升与变量声明提升 函数声明:以function开头的函数定义. js在执行代码之前会先读取函数声明和变量声明,函数声明整个提升,变量赋值在执行时再执行. cons ...

  7. python中def fun 定义函数列表_Python学习之 函数篇

    Python函数 函数就是完成特定功能的一个语句组,这组语句可以作为一个单位使用,并且给它取一个名字. 可以通过函数名在程序的不同地方多次执行(这通常叫函数调用). 函数定义要在函数调用之前,否则函数 ...

  8. 理解ROS服务和参数---ROS学习第6篇

    文章目录 1.ROS服务 2.使用rosservice 2.1 rosservice list 2.2 rosservice type 2.3 rosservice call 3. 使用rospara ...

  9. 以下是一个使用 VBA 的例子,演示了 ByVal 和 ByRef 的区别,以及如何在函数中传递参数和返回值。

    以下是一个使用 VBA 的例子,演示了 ByVal 和 ByRef 的区别,以及如何在函数中传递参数和返回值: Sub Example()Dim x As Integer, y As Integerx ...

最新文章

  1. python下载文件暂停恢复_python下载文件记录黑名单的实现代码
  2. AndroidSDK下载以及配置
  3. 【Linux】一步一步学Linux——apt-get命令(278)
  4. 部署 k8s Cluster(下)- 每天5分钟玩转 Docker 容器技术(119)
  5. AngularJs ng-repeat限制循环次数
  6. nedc工况_东南DX3 EV续航升级 NEDC综合工况续航451公里
  7. MySQL自定义函数(四十六)
  8. DataSet,DataTable,DateView的关系和用法
  9. 看完这篇,轻松解决FastReport合并单元格!
  10. 关于Qt作为第三方库,QGIS二次开发作为第三方库,Qt ui编译的一些问题
  11. HDFS的读写流程步骤(附图文解析)
  12. 计算机启动时为啥总要检测硬盘,每次开机都磁盘检查怎么办_如何关闭硬盘开机自检-win7之家...
  13. android局部布局刷新,Android RecyclerView 局部刷新分析
  14. android向DDR读写数据,透过数据看本质 -  被“吹爆”的LPDDR5内存究竟有多强大?...
  15. 字符串全排列与组合算法以及八皇后问题
  16. ug如何复制面_UG复制面,移动面,删除面,镜像面,替换面,阵列面命令用法与作用...
  17. dagum基尼系数分析全流程
  18. 谈谈什么是数据质量管理
  19. The Little Book of Mindfulness by Gilly Pickup
  20. .net 文字转语音简单应用 SpeedSynthesis,部署IIS

热门文章

  1. .net core上 K8S(七).netcore程序的服务发现
  2. 领域驱动设计,让程序员心中有码(二)
  3. ASP.NET Core中为指定类添加WebApi服务功能
  4. Jexus针对Asp.net core应用程序的六大不可替代的优势
  5. ZKWeb网站框架的动态编译的实现原理
  6. 在微信小程序中使用“随机键盘”
  7. 学妹,你要的C语言版AOE网络数据结构来了,就这么简单!
  8. 【经典回放】多种语言系列数据结构算法:队列(C版)
  9. JavaScript三种弹出框(alert,confirm和prompt)用法举例
  10. NDVI最大值法MVC合成之ArcGIS Cell Statistics 实现