Lua第一部分语言总结

本文深入浅出地介绍了Lua语言的基础概念,包括chunks、全局变量、数据类型、控制语句、函数特性等内容,并详细解析了闭包和迭代器的实现原理。

参考Programming in Lua,学习Lua的第一部分语言总结

一、chunks:一组放在一起的语句组。


二、全局变量:与nil相关。一个全局变量不是nil的时候即存在,是nil的时候即不存在。所以全局变量本身不需声明,与C++相比灵活。


三、八种变量:

1、nil:表示这个值没有

2、booleans:false和nil表示假,其余所有都是真

3、numbers:任意实数

4、string:单双引号都可以表示字符串,习惯使用双引号。字符串不可修改,即将a="one string"的one改为another,需要重新为a赋值,b=string.grusb(a,"one","another")。但是a不会改变。

string和number之间用是自动转换的

5、function:声明函数。可以认为任何一个函数都是一个变量。

6、userdata:后补充

7、thread:后补充

8:table:

(1)构造函数仅仅用于初始化,之后可以添加或删除

(2)无法调用的使用索引调用,且这一部分数据自己从1开始计算索引。

<span style="font-size:18px;">a={"xxx",x=1,y=2,"yyy"}

print(a[1])
print(a.x)
print(a.y)
print(a[2])
print(a[3])</span>
输出:

xxx
1
2
yyy
nil


四、运算符:

1、a==b:a和b类型不同则必不相同;Lua的比较通过引用比较,赋值也是通过引用赋值。所以,a和b声明内容相同(table,如果声明为一个普通内置变量则不成立),==时却不同。用a给c赋值,则a==c为真。

2、二元逻辑运算符,通过前一个元判断整体。若前一个元可以决定整体就返回前一个元,否则返回后一个元:

a and b:a为false则返回a,否则返回b

a or b:a为true则返回a,否则返回b

C++中的三元运算:a?b:c

lua中的三元运算:(a and b) or c


五、局部变量与代码块

local:局部变量,只在代码块中有效;在某些地方,使用类似于C++中的static

代码块:一个chunk,类似于C++中的{}。用do...end可以表示{}。

局部变量的使用主要要和注意交互模式,在交互模式中可以使用do...end可以表示{}。


六、控制语句

1、与C++相比,用repeat...until代替了do...while

2、for有两类

(1)数值for循环:

for i=var1(开始),var2(终止),var3(步长,默认1,可省略) do

end

以上声明方式导致var都是for的local,出了for就没用了

三个var只在循环开始前做一次计算,不再修改


(2)泛型for循环:遍历迭代子函数返回的每一个值,后补充


七、函数

1、可以多个返回值。当函数调用是参数中的唯一参数或者最后一个参数的时候,尽量多的返回返回值;其余情况下只能返回第一个值。

<span style="font-size:18px;">function foo()
	return 1,2;
end

x,y=foo(),3

print(x)
print(y)</span>
打印1,3

<span style="font-size:18px;">function foo()
	return 1,2;
end

a={foo(),3}
print(a[1])
print(a[2])
print(a[3])</span>
打印 1,3,nil

2、函数的命名参数的使用:简而言之就是将多个参数放到一个表中,在函数中,通过表调用函数

<span style="font-size:18px;">nametable={oldname="old",newname="new"}

function rename(arg)
	return os.rename(arg.oldname,arg.newname)
end</span>
3、高级函数:函数的参数中有另一个函数即称为是高级函数

4、关于闭包:一个嵌套在函数的函数和其外部函数中的local变量共同构成

<span style="font-size:18px;">function counter()
	local i=0;  --<span style="color:#ff0000;">类似于C++中的static</span>
	return function()   --匿名函数
		i=i+1;
		return i;
	end
end

c1=counter();
c2=counter();

print(c1());  --c1作为一个闭包
print(c1());  --同一个c1闭包
print(c2());  --另一个闭包c2
</span>
输出:

1
2
1

对比:

<span style="font-size:18px;">function add(i)
	i=i+1;
	return i;
end

function counter()
	local i=0;
	return add(i);

end

c1=counter();
c2=counter();

print(c1);  --c1作为一个闭包
print(c1);  --同一个c1闭包
print(c2);  --<span style="font-family: KaiTi_GB2312;">同</span>一个闭包
</span>

输出:

1
1
1

对比:

<span style="font-size:18px;"><span style="background-color: rgb(255, 255, 255); font-family: KaiTi_GB2312; font-size: 18px;"></span><pre name="code" class="plain">function counter()
	i=0;  --类似于C++中的static
	return function()   --匿名函数
		i=i+1;
		return i;
	end
end

c1=counter();
c2=counter();

print(c1());  --c1作为一个闭包
print(c1());  --同一个c1闭包
print(c2());  --另一个闭包c2</span>


输出:

123

5、局部函数递归定义的时候需要先声明再使用,否则在调用递归的时候会先寻找全局函数中相同名字的函数寻求调用:

<span style="font-size:18px;">function fact(n)
	return n;
end

local fact=function(n)
	if n==0 then
		return 1;
	else
		return n*fact(n-1);
	end
end

print(fact(5))
</span>
输出是20。表示第一次调用的是local,递归的第一次调用是全局的fact

6、尾调用:函数的最后一个动作是调用其他函数,像是goto一样

<span style="font-size:18px;">function f()
	return g();
end</span>
调用g()后,不需要再栈中保留f的相关信息,所以尾调用用于递归可以无限制。


八、迭代器

迭代器支持指针类型的结构,遍历集合所有元素,使用函数描述迭代器,每次调用迭代器函数都要返回集合的下一个元素。迭代器保留上一次成功调用的状态和下一次成功调用的状态。

闭包:闭包本身+创建闭包的工厂

迭代器要和闭包结合起来,代码如下:

<span style="font-size:18px;">function list_liter(t)   --创建闭包的工厂
	local i=0;
	local n=table.getn(t);
	return function()   --和以上的两个local构成一个闭包,即通过i保存了每上一次和下一次的所有调用状态
		i=i+1;
		if i<=n then
			return t[i];
		end
	end
end

t={1,2,3};
itor=list_liter(t);

while true do
	local element=itor();

	if element==nil then
		break;
	end

	print(element);
end
</span>

迭代器可以分为无状态的迭代器和多状态的迭代器,但是尽量写无状态迭代器;其次使用闭包。尽量不用使用table的多状态迭代器。


九、泛型for

上一个代码例子可以用泛型for遍历

<span style="font-size:18px;">function list_liter(t)
	local i=0;
	local n=table.getn(t);
	return function()   --和以上的两个local构成一个闭包,即通过i保存了每上一次和下一次的所有调用状态
		i=i+1;
		if i<=n then
			return t[i];
		end
	end
end</span>
<span style="font-size:18px;">t={1,2,3};
for elemment in list_liter(t) do
	print(elemment)
end</span>

(1)泛型for的表达式:

for <var-list> in <exp-list> do
<body>
end
<var-list>:变量列表名列表,第一个变量是控制变量,为nil的时候循环结束

<exp-list>:表达式列表,一般只有一个值,就是迭代工厂
(2)运行步骤:

[1]计算表达式,返回三个值,迭代函数,状态常量,控制变量

[2]调用迭代函数,参数是状态常量和控制变量

[3]将迭代函数的返回值赋值给变量列表,检查控制变量

<span style="font-size:18px;">for var1,var2,...,varn in explist --var1是控制变量
	do block
end</span>
以上代码等价于

<span style="font-size:18px;">do
	local f,s,var=explist --f表示迭代函数,s表示状态常量,var控制变量
	while true do
		local var1,var2,...,varn=f(s,var);
		var=var1
		
		if var==nil then
			break;
		end
	end
end</span>


九、dofile,loadfile,loadstring,require区别:

Lua将代码预编译为中间码再执行。解释型语言的特征是编译器是语言运行时的一部分。

dofile:编译+执行。可以认为是loadfile+错误保护机制。每次编译每次执行。

loadfile:编译但不执行,本身就可以返回错误信息。一次编译多次运行。

loadstring:功能强大但陷阱多。读入一个字符串当做一个函数做处理

require:类似于dofile,但是会搜索目录加载文件且可以避免重复加载同一文件,尽量使用这个。


Lua中的函数定义时发生在运行时的赋值而不是编译时

loadfile:编译但不执行的理解用例

-- file `foo.lua'
function foo (x)
	print(x)
end
如果只执行f=loadfile("foo.lua"),则foo仅仅被编译,没有定义
f()				-- defines `foo'
foo("ok")		--> ok

loadstring:

调用loadstring时,只寻找全局变量做操作。对local变量无法找到




第三方支付功能的技术人员;尤其适合从事电商、在线教育、SaaS类项目开发的工程师。; 使用场景及目标:① 实现微信与支付宝的Native、网页/APP等主流支付方式接入;② 掌握支付过程中关键的安全机制如签名验签、证书管理与敏感信息保护;③ 构建完整的支付闭环,包括下单、支付、异步通知、订单状态更新、退款与对账功能;④ 通过定时任务处理内容支付超时与概要状态不一致问题:本文详细讲解了Java,提升系统健壮性。; 阅读应用接入支付宝和建议:建议结合官方文档与沙微信支付的全流程,涵盖支付产品介绍、开发环境搭建箱环境边学边练,重点关注、安全机制、配置管理、签名核心API调用及验签逻辑、异步通知的幂等处理实际代码实现。重点与异常边界情况;包括商户号与AppID获取、API注意生产环境中的密密钥与证书配置钥安全与接口调用频率控制、使用官方SDK进行支付。下单、异步通知处理、订单查询、退款、账单下载等功能,并深入解析签名与验签、加密解密、内网穿透等关键技术环节,帮助开发者构建安全可靠的支付系统。; 适合人群:具备一定Java开发基础,熟悉Spring框架和HTTP协议,有1-3年工作经验的后端研发人员或希望快速掌握第三方支付集成的开发者。; 使用场景及目标:① 实现微信支付Native模式与支付宝PC网页支付的接入;② 掌握支付过程中核心的安全机制如签名验签、证书管理、敏感数据加密;③ 处理支付结果异步通知、订单状态核对、定时任务补偿、退款及对账等生产级功能; 阅读建议:建议结合文档中的代码示例与官方API文档同步实践,重点关注支付流程的状态一致性控制、幂等性处理和异常边界情况,建议在沙箱环境中完成全流程测试后再上线。
matlab2python 这是一个Python脚本,用于将Matlab文件或代码行转换为Python。此项目处于alpha阶段。 该实现严重依赖于Victor Leikehman的SMOP项目。 当前实现围绕SMOP构建,具有以下差异: 力图生成不依赖libsmop的代码,仅使用如numpy这样的标准Python模块。 使用常见缩写如np而非全称numpy。 尝试重排数组和循环索引,从0开始而不是1。 不使用来自libsmop的外部类matlabarray和cellarray。 增加了对Matlab类的基本支持,类体中声明的属性在构造函数中初始化。 因上述改动,产出代码“安全性较低”,但可能更接近用户自然编写的代码。 实现相对直接,主要通过替换SMOP使用的后端脚本,这里称为smop\backend_m2py.py。 一些函数替换直接在那里添加。 额外的类支持、导入模块以及其他微调替换(或说是黑客技巧)在matlabparser\parser.py文件中完成。 安装 代码用Python编写,可按如下方式获取: git clone https://github.com/ebranlard/matlab2python cd matlab2python # 安装依赖项 python -m pip install --user -r requirements.txt # 让包在任何目录下都可用 python -m pip install -e . # 可选:运行测试 pytest # 可选:立即尝试 python matlab2python.py tests/files/fSpectrum.m -o fSpectrum.py 使用方法 主脚本 存储库根目录下的主脚本可执行,并带有一些命令行标志(部分直接取自SMOP)。要将文件file.m转换为file.py,只需输入:
【信号识别】识别半监督粗糙模糊拉普拉斯特征图(Matlab代码实现)内容概要:本文档围绕“信号识别”主题,重点介绍了基于半监督粗糙模糊拉普拉斯特征图的信号识别方法,并提供了完整的Matlab代码实现。该方法结合了半监督学习、粗糙集理论、模糊逻辑与拉普拉斯特征映射技术,用于提升在标签样本稀缺情况下的信号分类性能,尤其适用于复杂背景噪声下的信号特征提取与识别任务。文中详细阐述了算法原理、数学模型构建过程及关键步骤的编程实现,旨在帮助科研人员深入理解并应用该混合智能识别技术。; 适合人群:具备一定信号处理基础和Matlab编程能力的研究生、科研人员及从事通信、雷达、电子系统等领域工程开发的技术人员;熟悉机器学习与模式识别的基本概念者更佳; 使用场景及目标:①应用于低标注成本、高噪声环境下的信号分类任务,如雷达信号识别、通信信号监测等;②用于学术研究中对半监督学习与特征降维融合方法的探索与性能验证;③作为撰写相关领域论文或项目开发的技术参考与代码基础; 阅读建议:建议读者结合文档中的理论推导与Matlab代码逐段分析,动手运行并调试程序以加深理解;可尝试在不同信号数据集上进行实验对比,进一步优化参数设置与模型结构,提升实际应用场景下的识别精度与鲁棒性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值