Lua学习笔记--函数初探

Lua 函数 介绍Lua函数基本原理及应用 阅读详情

感觉学习语言的话,函数是个重头戏。来看一下Lua的函数是神马样纸的东东!


一.简单的函数例子

--一个简单的函数:阶乘
function factorial(num)
	if num == 0 then
		return 1
	else
		return num * factorial(num - 1)
	end
end
恩,这就是个函数。function关键字,说明这是个函数,然后是函数名,后面跟的是参数列表,使用括号括起来。函数的结尾需要一个end关键字,表明函数结束了。

下面看以下怎么调用:
--一个简单的函数:阶乘
function factorial(num)
	if num == 0 then
		return 1
	else
		return num * factorial(num - 1)
	end
end
--调用函数的例子:输入一个数字,求其阶乘
line = io.read()
n = tonumber(line)
if n == nil then
	print("input is not a valid num")
else
	print(factorial(n))
end
结果:
5
120
请按任意键继续. . .

调用函数时,有几个地方需要注意一下:

1.当函数后面只有一个参数,并且这个参数是字符串或table构造式时,可以省略括号。
比如:
--函数后面只有一个参数,且为字符串
print "hello world"

--函数后面只有一个参数,且为table构造式
print {x = 10, y = 20}
结果:
hello world
table: 003BEC40
请按任意键继续. . .

2.调用函数时,给出参数如果和要求不符时,不会报错,处理策略采用:参数多了的舍弃,少了的为nil
function myprint(a, b, c)
	print(a, b, c)
end

--正常调用
myprint(1, 2, 3)
--参数多了
myprint(1, 2, 3, 4)
--参数不足
myprint(1, 2)
结果:
1       2       3
1       2       3
1       2       nil
请按任意键继续. . .

二.多重返回值

记得刚学C语言的时候,还不会神马通过指针参数返回参数的方法,当时就特别纠结,要是有多个返回值得肿么办,不过慢慢就习惯了,通过结构体啦,或者指针或者引用实参传递多个参数了。没想到Lua竟然支持多重返回值!!!真的是灰常强大的设定!

一个例子:
--赶脚灰常牛的特性,多个返回值

--一个接受一个table的函数,返回最大元素以及该元素的位置
function maxinum(a)
	local index = 1
	local max = a[index]
	for i, val in ipairs(a) do
	 if val > max then
		max = val
		index = i
	 end
	end
  return max, index
end

--测试
a = {1, 2, 3, 10, 4, 8, 5, 7}
print(maxinum(a))
结果:
10      4
请按任意键继续. . .

当然,多重返回值也不是任何时候都触发的,Lua会根据不同的情况进行调整。在以下四种情况时,会触发多重赋值:
1.多重赋值
2.函数调用传入实参列表
3.table构造式
4.return语句

针对不同的情况,看几个例子

1.多重赋值

--多重返回值demo
function func()
	return 1, 2, 3
end

--正常的多重赋值,按照顺序进行多重赋值,返回值个数多了的舍去,少了的取nil
a , b, c = func()
print(a, b, c)

--若函数是多重赋值的最后一个或者唯一一个表达式,那么会尽可能的保留其返回值
a, b, c = 0, func()
print(a, b, c)

--若函数不是最后一个的话,则只产生一个返回值
a, b, c = func(), 0
print(a, b, c)
结果:
1       2       3
0       1       2
1       0       nil
请按任意键继续. . .

2.函数调用传入实参列表

--多重返回值demo
function func()
	return 1, 2, 3
end

--接受固定参数的myprint()
function myprint(a, b, c)
	print(a, b, c)
end

--当仅有或者为最后一个形参时,会尽可能保留其返回值
print(func())
--myprint仅接受三个参数
myprint(0, func())
--函数表达式为不为最后一个时,仅保留一个返回值
print(func(), 1)
结果:
1       2       3
0       1       2
1       1
请按任意键继续. . .

如果函数出现在一个表达式中,lua会自动将返回值个数调整为1个,即第一个。
--多重返回值demo
function func()
	return 1, 2, 3
end

--当有()括起函数时,即形成了一个表达式,不管函数返回几个值,仅取一个值
print((func()))
结果:
1
请按任意键继续. . .


3.table构造式

table比较强大,类似vector,想装多少装多少,所以,我们在table构造式中返回的值都可以被其吸收。不过,这个行为也是和之前的一样,仅当只有一个函数作为构造实参时或者函数为最后一个构造实参时才有这种效果,否则又是仅返回一个值。
--多重返回值demo
function func()
	return 1, 2, 3
end

--打印table中所有值的函数
function myprint(a)
	for i, v in ipairs(a) do
		print(v)
	end
	print("--------------------------------")
end

--当仅有一个或者是最后一个构造实参时
a = {func()}
myprint(a)

a = {0, func()}
myprint(a)
--当不是最后一个时,仅能返回一个值
a = {func(), 0}
myprint(a)
结果:
1
2
3
--------------------------------
0
1
2
3
--------------------------------
1
0
--------------------------------
请按任意键继续. . .


4.return语句

return语句本身要返回另一个函数的多个返回值,所以这个时候也支持多个函数的返回值。
例如:

--多重返回值demo
function func()
	return 1, 2, 3
end

--return多个结果

function func2()
	return 1,func()
end

function func3()
	return func(),1
end

--func2调用func1,func1在最后会返回1,2,3
print(func2())

--func3调用func1,func1不在最后,仅返回1
print(func3())


结果:
1       1       2       3
1       1
请按任意键继续. . .


三.变长参数

这个也是个棒棒哒的特性。使用...表示是变长参数。函数的形参设定为(...)即表明这个函数接受变长参数。一个例子:
--变长参数

--...表示变长参数,使用for循环遍历其中的内容
function add(...)
	local sum = 0
	for i, v in ipairs{...} do
	sum = sum + v
	end
	return sum
end
--使用函数
print(add(1, 2, 3, 4, 5))
结果:
15
请按任意键继续. . .

这里要注意的是,参数使用这个...表示,这里面将参数作为一个{...}数组来遍历。

关于...其实还是和多返回值的各种特性差不多:
--变长参数

--func
function func(...)
	--直接打印这些参数
	print(...)
	--赋值(多了的舍去,少了的nil)
	a, b = ...
	print("a, b = ", a, b)
	--使用(...)表示只取得第一个
	return (...)
end

print(func(1,2,3))
结果:
1       2       3
a, b =  1       2
1
请按任意键继续. . .

 
关于可变参数,可以使用select关键字来取得第几个参数。
--关于可变参数的另一种遍历方式
function func(...)
	for i = 1, select('#', ...) do
	local arg = select(i, ...)
	print(arg)
	end
end

func(1, 2, 3, 4)
结果:
1
2
3
4
请按任意键继续. . .


四.具名实参

具名实参,给我的赶脚就像一个结构体。我们传递一堆参数进来之后,经常忘记这个参数是干神马的,以至于最后调用的时候弄错了。所以,这时候,就像C语言那样,传递一个结构体进来,根据结构体的不同字段,进行操作就不会弄错了。
Lua中,实现的方法就是使用那个万能的table。具体的注意事项都在例子中写出:
--参数使用一个table的构造式,根据其中不同的字段获取其值
function Window(option)
	--这里将参数的各个字段打印一遍
	print(option.x or 0)--后面的为默认值,如果option.x为nil,则使用默认值
	print(option.y or 0)
	print(option.width or 800)
	print(option.height or 600)
	print("-------------------------------------------")
end

--当参数只有一个table的构造式时,可以省略括号
Window{x = 100, y = 200, width = 1000, height = 800}
--当有参数没给出时,会使用默认参数
Window{x = 100}
--顺序不一样也是可以的哈
Window{y = 100, width = 1000, x = 100, height = 800}
结果:
100
200
1000
800
-------------------------------------------
100
0
800
600
-------------------------------------------
100
100
1000
800
-------------------------------------------
请按任意键继续. . .


函数入门暂时就这些,还有一个unpack的函数,可以返回table中所有的内容,不过在我的电脑上一直没能试验成功,留个坑。














C 函数中调用Lua函数时,对于lua_pcall使用的困惑 最近在学习使用Lua,也通过基本的语法知识完成了公司的一个关于配置文件参数合法性检查的小任务。虽然任务完成了,但对于一些函数的调用目的还是搞不明白,这两天再次重看了Manual Reference,稍微梳理出了一点眉目,记录在此。 首先看一段小小小程序 //test.lua 阅读详情

相关推荐

【Lua 语言】Lua 调用 C 函数

Lua 提供了调用 C 函数的接口,这样我们可以开心地用 C 来写一些底层的代码供 Lua 调用了。调用方式如下:1. 新建 C 源文件,将需要被 Lua 调用的函数实现如下:static int l_add(lua_State *L){    return 0;}...

appleeated的博客 1742

Lua求n的阶乘

首先要明白n的阶乘的具体算法,n的阶乘是指从:(n)乘(n-1)乘(n-2)…乘1,值得注意的是0的阶乘是1。递归函数实现求n的阶乘function factorial(n) if n == 0 then return 1; else return n * factorial(n - 1); end end

我只是一个普通的Coder 2047

DELPHI中集成LUA脚本学习笔记2_调用LUA函数(详)

<br />详细研究了一下主程序调用LUA函数的细微过程,顺便写一点心得<br />调用LUA函数<br /><br />function add(x, y)<br /> return x+y<br />end<br /><br />在已经打开LUA库并装载了脚本后主程序使用以下方法调用<br /><br />lua_getglobal(L, "add");//压入被调用的LUA中函数名add<br />lua_pushnumber(L, x); //压入add的第1个参数<br />lua_pushnum

靠别人不如靠自已。 3859

Lua语言之阶乘函数的实现

--函数 function fact(num) local sum = num for i=num,2,-1 do sum = sum*(i-1) print(sum) end return sum end --测试代码 print(fact(4))

isS_MK_GmbH的博客 1256

C++ 调用 Lua 函数

Lua 作为一门脚本语言,可以作为 “配置文件”、“动态逻辑脚本” 等角色作用于宿主程序。1. Lua 会处理语法细节,后续维护简单,并且可以有注释。2. 可以编写逻辑,达到复杂的配置。如果我们的程序需要进行一些 “下发配置” 时,一般会考虑选择 “json”、“文件” 等形式。但是如果 “配置” 内容较为复杂,则可以考虑 Lua 了,具体可以查看以下分享。Github传送门(如果对你有所帮助或喜欢的话,赏个star吧,码字不易,请多多支持)如果觉得本篇博文对你有所启发或是解决了困惑,。

江澎涌的博客 1404

ros2笔记-4.6使用launch启动脚本

ros2 4.6 使用launch启动多节点

bohu83的博客 1311

lua 计算阶乘

代码如下: function fact(n) --function 声明一个函数 函数名 if n == 0 then return 1 else return n * fact(n-1) end --if 函数结束 类似while for do .... end

学习这件事,不是缺乏时间,而是缺乏努力。 2528

简单初识 Material Point Method(MPM)

简单初识 Material Point Method(MPM):先介绍了Lagrangian和Eulerian,并简单介绍了MPM Method

qq_45776432的博客 7365

lua用递归方法实现求阶乘数

递归是什么,递归怎么运行呢? 递归其实就是一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法。 一般来说递归其实就是在运行中调用自己。 那么阶乘的公式是n X (n-1) 记住0的阶乘数为1. 做阶乘必须先写一个函数。 然后用if(如果)的判断语法。 a0是判断a是否等于零的意思。 这个是过程 return1我们先放在一边不管我们先说return anumber (a-1) 这就...

flowerX2的博客 863

使用ACOLITE对OLCI影像进行大气校正+批处理

使用ACOLITE对OLCI影像进行大气校正+批处理

mrzhy1的博客 7359

YOLOv8训练流程-原理解析[目标检测理论篇]

本篇文章主要介绍了YOLOv8训练的流程,主要介绍了Task Aligned Assigner正负样本匹配策略以及YOLOv8的损失计算。

ice 4516

[LUA学习笔记03]LUA函数和C函数的相互调用

  1. 简介LUA和C之间的函数调用也是基于上一节提到的栈。 1.1 从C程序调用LUA函数LUA的函数和普通变量一样也是First Class Variable类型,可以看作函数指针变量参与栈操作。因此调用过程分为如下几个步骤: 请求LUA函数(指针)入(GLOBAL)栈。 将函数需要的参数入栈,入栈顺序按照参数被声明的顺序。 告知LUA虚

MrTECHNO的编程日记 7953

STM32入门教程:水位传感器应用

这是一个简单的STM32水位检测系统的入门教程。希望通过学习本教程,您能对STM32微控制器的基本应用有更深入的了解,并能成功构建一个水位检测系统。如果您需要更详细的代码实例和教程,请参考相关的STM32开发手册和应用笔记。STM32是一款功能丰富且广泛应用于嵌入式系统的微控制器系列。在本教程中,我们将介绍如何使用STM32微控制器和水位传感器构建一个水位检测系统。

wx_linying1029的博客 533

Lua学习笔记--Lua调用C初探

上次学习了怎么用C调用Lua的函数,并返回一个结果,这次看看怎么反过来,用Lua调用C的函数。 一.简介 C调用Lua函数比较简单,只需要操作相关的栈就可以了,但是Lua调用C的话,稍微有一点麻烦,虽然还是用栈来进行数据的传递,但是由于Lua中本身没有C中写的函数,所以需要多一步将C函数注册到Lua中的步骤。 Lua反过来调用C函数的话,首先,我们要写一个要被调用的函数,这个函数有一个格式的

puppet_master的专栏 1052

ESP32-CAM 赋能 AI 视觉巡检小车:自主避障与目标追踪实现全解析

本文基于 ESP32-CAM 实现了低成本 AI 视觉巡检小车的核心功能,硬件成本<100 元,兼顾自主避障与目标追踪。算法升级:移植 YOLOv5nano 量化模型(INT8),提升目标检测精度(如识别巡检场景中的 “异常物体”“人员”);无线拓展:通过 MQTT 协议将巡检图像、距离数据上传到阿里云 / 腾讯云,实现远程监控;多传感器融合:增加温湿度(DHT11)、红外测温(MLX90614)模块,扩展巡检维度;路径规划:结合 SLAM 算法,实现自主建图与路径巡检。

weixin_42300449的博客 367

QT-Creator安装教程(windows)

本文介绍了Qt的下载安装步骤:1)通过镜像源下载安装包;2)运行exe文件时使用命令行参数指定镜像地址;3)在安装过程中选择路径和自定义安装组件,包含QT5和QT6版本的详细安装说明;4)安装后可继续添加扩展包或卸载组件。重点提示了QT6必须勾选的关键组件,并提供了组件管理的操作方法。

qq_53545309的博客 3102

DELPHI中集成LUA脚本学习笔记1_初探LUA

<br />序:记得在刚开始学编程的时候,知道了一个字符串并不是一定要在程序中固定死的,而是可以用TEdit.Text来连接的,于是有了一个想法,把一整段代码(几个函数)放在Memo中,想在程序运行的时候通过修改Memo中的内容而让程序能灵活使用.可惜后来失败了.大家看到这一定会笑的半死.的确这是一个很幼稚的想法.后来知道用脚本可以实现程序的灵活运行,可惜一直没有时间研究,这几天刚好要用到脚本,所以研究了一下午,顺便写一点心得.<br />Python,LUA等都不错,我选择了LUA原因是连接库比较小,扩展

靠别人不如靠自已。 1642

157、飞控中的鲁棒自适应控制

本文总结了飞控系统中鲁棒自适应控制的实践经验。作者通过炸机案例引出传统PID控制的局限性,分析了鲁棒性与自适应性的本质矛盾,提出"用鲁棒性兜底,用自适应性提性能"的设计原则。重点介绍了模型参考自适应控制(MRAC)的实现方法,包括参考模型设计、自适应律调参技巧(建议初始增益设为0.01)、直接/间接自适应的应用场景差异,以及防止参数漂移的鲁棒修正方法。文章还分享了实际调试中的三大关键问题(初始值设定、激励条件、执行器饱和)及解决方案,并推荐了"鲁棒PID+自适应前馈"的混合架构。最后强调调试顺序应为先保证鲁

2401_88858637的博客 27

LUA学习笔记

LUA学习笔记 本文从Programming in Lua中提取 使用LUA的目的: 当你真正要在项目中使用LUA时会明白自己的选择: 为了程序的可扩展性和随意性,减少后期需求的变化进项目造成的影响.   本文只介绍一些很肤浅关于LUA的C环境构建,及一些简单的LUA函数应用,是自己使用LUA的总结和入门记录.   LUA将给程序带来的功能: 1.LUA可以当一个配置文件使用(读

xinxun的地盘 1万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Lua学习笔记二--在Lua中使用自己的C函数收藏

  Lua学习笔记二--在Lua中使用自己的C函数收藏 新一篇: Lua学习笔记三--表的应用 | 旧一篇: Lua学习笔记一 function StorePage(){d=document;t=d.selection?(d.selection.type!=None?d.selection.createRange().text:):(d.getSelection?d

skyremember的专栏 2007

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

初探Lua脚本

Lua初探,结合Redis+Lua Demo演示

weixin_43410352的博客 9263

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Lua中调用C函数

Lua中调用C函数Lua利用一个虚拟的堆栈来给C传递值或从C获取值1. C函数作为应用程序的一部分2. C函数库成为Lua的模块Lua中调用C函数Lua调用c模块 https://www.cnblogs.com/sifenkesi/p/3876745.html https://blog.youkuaiyun.com/liu943367080/article/details/90909005 Lua利用一个虚拟的堆栈来给C传递值或从C获取值 Lua利用一个虚拟的堆栈来给C传递值或从C获取值。每当Lua调用C函数,都会获得

宁静致远的博客 3922

Lua学习笔记04:Lua函数简介

Lua函数 一、在Lua中,函数是对语句和表达式进行抽象的主要方法。既可以用来处理一些特殊的工作,也可以用来计算一些值。 Lua 提供了许多的内建函数,你可以很方便的在程序中调用它们,如print()函数可以将传入的参数打印在控制台上。 Lua 函数主要有两种用途: 1.完成指定的任务,这种情况下函数作为调用语句使用;print("Hello World") 2.计算并返回值,这种情况下函数作为赋...

qq_42483286的博客 753

XLUA学习笔记之C#和Lua之间的相互调用

感觉学习的笔记还是放在网上查询的时候比较方便,文章初看会感觉很难理清,需要耐心去看,对不起自己对不起翻到我文章的同学,不废话直接上代码。 1.C#调用Lua (耐心!耐心!耐心!) using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using XLua; //这...

xmx5166的博客 7434

Lua 函数用法探究

在Lua 基本语法快速入门 中有涉及到函数的用法,但只是普通的应用,并没有深成次的研究一下,介于函数用的还是比较多的就专门做个专题研究一下~     一、函数、变量的用法              函数的定义用关键字function 。然后加函数名和变量。注意后面没有do。最后以end结束。              在函数中的变量默认是全局变量,但通常情况下函数中的变量都是在函数中有效

阿修罗道 5602
上一篇: Lua学习笔记--基本语法规则&控制流语句
下一篇: Lua学习笔记--table
puppet_master
puppet_master 领域专家: C/C++技术领域 领域专家: C/C++技术领域
博客等级 码龄12年 2695粉丝 161原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值