lua loadstring传递参数_lua学习之函数篇

45c0f9bba79c8019b958af64325bed1b.png

函数

  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)    )    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/297978.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

EF Core 6 简化的数据库上下文注册

EF Core 6 简化的数据库上下文注册IntroEF Core 6 将简化现在的服务注册,DbContext 的服务注册将会更简单一些Sample直接来看示例代码吧:现在我们注册 EF Core 的 DbContext 通常是这样的:const string connectionString "DataSourcete…

快要“成精”的波士顿机械狗,开始卖了,价格不贵准备搞一只

全世界只有3.14 % 的人关注了爆炸吧知识重磅消息:这只全球著名的网红狗终于。。开!售!了!哦,不对,放错图了!应该是这只!一起来看看视频介绍——6月17日,据科技时报&#…

BeetleX.WebFamily文件图片管理集成

BeetleX.WebFamily在2.4.8版本中集文件管理功能,通过这一功能可以不写任何代码的情况即可集成文件和图片的上传管理功能。接下来详细介绍下如何引入这一功能组件。文件管理功能是基于Vue和Element,所以只有在BeetleX.WebFamily中使用Vue和Element模板才能…

怎么部署_2020怎么部署新零售商城?

移动电子商务的发展壮大,5g网络技术的扶持,新零售概念时代推动店家完成零售转型,网上零售商城,再加上线下与推广线下的玩法,带来了效率和效益的提升。一,运用社交媒介,大力发展新零售概念下的销…

python self 值自动改变,在python中对self的理解

在python中对self的理解 :一、self的位置是出现在哪里?首先,self是在类的方法中的,在调用此方法时,不用给self赋值,Python会自动给他赋值,而且这个值就是类的实例--对象本身。也可以将self换成别…

各种震撼的慢镜头,奇怪的知识又增加了!​

全世界只有3.14 % 的人关注了爆炸吧知识慢镜头(高速摄影)可能是现代最伟大的发明之一。从身边的日常到那些比较罕见的事物,慢镜头下看起来都比平时更酷!喵星人接球这行云流水的动作,秒杀国足!这是用多台风扇…

Dapr牵手.NET学习笔记:跨物理机负载均衡服务调用

dpar在同一台电脑上不能run 相同appid,这个在上篇说过,所以就用外部负载均衡nginx来对应,那在不同的host中跑同一服务,看看dapr内部的负载均衡是怎么实现的。说说现有的服务,两个服务,订单服务,…

电脑编程教学_2020太原数控车床电脑编程一对一实操教学不限学时

2020太原数控车床电脑编程一对一实操教学不限学时石家庄工之艺数培训学校培训‘数控技术员’ 学生时,拿到图纸和毛坯,能够自己的在数控机床上做出成品。实行教学,“小班授课,一对一的教,理论实践相结合,随到随学&#…

多功能复合机基于用户认证功能的实现过程详解

多功能复合机基于用户认证功能的实现方法 -----网络设备共享案例分析 公司需求:***是一家租售写字楼的服务性企业,主要是针对小型企业进行出租,房间有大有小,大的可以容纳5-10人,小的可以容纳1-4人左右。由于都是一些小…

用python写简单爬虫,用Python写简单的爬虫

准备:1.扒网页,根据URL来获取网页信息importurllib.parseimporturllib.requestresponse urllib.request.urlopen("https://www.cnblogs.com")print(response.read())urlopen方法urlopen(url, data, timeout)url即为URL,data是访问U…

单元测试(二)基本使用争议篇

介绍常用的单元测试是测试方法、API等,下面我们来演示一下Xunit测试框架的简单使用,有些是为了演示而写的单元测试。最下面有反转,一定要看到最后操作创建单元测试项目本次文章还在原来项目的基础上进行操作,右键解决方案添加单元…

听说你趁我不在家,欺负我老婆?

1 听说你趁我不在家欺负我老婆了?▼2 当男生们聚在一起时他们都会做什么?▼3 其实我是广西人,每顿要嗦1吨粉▼4 山西人的饮水机里放的都是醋?▼5 可现实中又有几个总裁没有啤酒肚呢?▼6 开学考试,一考…

RHEL5.3下MRTG+SNMP的搭建

一、MRTG的简介 Mrtg(Multi Router Traffic Grapher,MRTG)是一个监控网络链路流量负载的工具软件,它通过snmp协议从设备得到设备的流量信息,并将流量负载以包含PNG格式的图形的HTML文档方式显示给用户,以非常直观的形式显示流量负载(可以在网…

BeetleX.WebFamily之Markdown编辑器

组件的新版集成一款Markdown编辑器ToastUIEditor,通过它可以快速地构建编写Markdown文本内容功能。集成后的ToastUIEditor支持图表,表格,文件管理插入等功能。新建一个控制台项目,通过Nuget引用组件后编写以下代码class Program {…

如何逃离「信息茧房」?

全世界只有3.14 % 的人关注了爆炸吧知识智能算法、内容推荐,当我们滑动屏幕的时候,映入眼帘的总是我们想看的内容。不过,这样的内容选择或许会让我们陷入「信息茧房」:只注意自己选择的、让自己愉悦的资讯,久而久之和蚕…

oracle表存储表空间,Oracle的存储信息-表空间信息记录

经过前面的介绍,我们已经能够对Oracle的存储结构有了深入的了解,总结一下前面的内容:Oracle最小的数据存储单位是数据块(Block),如果以单个数据块进行对象空间分配,那么显然分配将过于频繁,所以Oracle使用多…

排序算法java实现

1. 插入排序 原理:遍历到第N个元素的时候前面的N-1个元素已经是排序好的了,那么就查找前面的N-1个元素把这第N个元素放在合适的位置,如此下去直到遍历完序列的元素为止。 算法的复杂度也是简单的,排序第一个需要1的复杂度&…

FusionChart完全入门手册 -2

今天主要探讨下,数据文件的生成方式,只做探讨。 其实funsioncharts提供了多种数据展现方式,除了前一节采用的直接的DATAFile的方式外,还有官方提供的标准的c#实现方式。 看个截图 但是总感觉使用官方提供的InfoSoftGlobal不是很灵…

BeetleX.WebFamily之ElasticSearch搜索集成

组件在最新版本中集成了基于ElasticSearch的文档搜索功能,通过这一功能可以快速地构建文档查询的webapi服务和web搜索应用。接下来介绍一下如果使用组件的ElasticSearch组件来进行文档构建和查询。ElasticSearch要求组件支持7.x和6.x两个版本的ElasticSearch服务&am…

直男们给我看清楚!这才是小姐姐的真面目......

1 这才是化妆的真相!▼2 听说,这就是当年Tom劈过得那棵树▼3 等一下!这题真的有正确答案吗?▼4 这是一只长大成熟的猫咪了▼5 想当年上学的时候转书、转笔都一门灵,就是脑子不会转▼6 猫的四肢和尾巴仿佛都有独立…