【Lua学习笔记】Lua入门
文章目录
- Lua变量
- 数据类型
- 变量声明
- 其他表示
- Lua语法
- 判断
- 逻辑判断(Lua很特殊,这个比较重要)
- 短路判断
- if
- if else
- 循环
- while
- for
- repeat
- 迭代器
- 泛型for迭代器
- 无状态迭代器
- 多状态的迭代器
- Lua函数
- select方法
- 数组
- 字符索引
- _G
(不是教程,推荐有编程基础的人观看本文)
文中主要包含了对菜鸟教程中的一些学习理解,个人感觉Lua语言和Python很多地方相似
以下大部分代码和表格摘抄自菜鸟教程
function start()
Lua变量
数据类型
数据类型 | 描述 |
---|---|
nil | 只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)(类似与Null或者None) |
boolean | false和true |
number | 双精度浮点数 |
string | 字符串由一对双引号或单引号来表示 |
function | 由 C 或 Lua 编写的函数 |
userdata | 表示任意存储在变量中的C数据结构 |
thread | 表示执行的独立线路,用于执行协同程序(那你为啥叫线程?) |
table | Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字、字符串或表类型。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。 |
变量声明
a = 5 -- 全局变量
local b = 5 -- 局部变量
在Lua中,使用local显示声明该变量为局部变量,而不声明的都是全局变量。
a -- nil
a = 5 -- number
a = false -- bool
a = "" -- string,单双引号都可以,支持转义字符,print出空字符串而非nil
在lua中字符串尾部没有\0,而且\0即使在字符串中也不代表结束且不计入长度
我们也可以用16进制来定义字符串
s = string.char(0x30,0x31)
n = string.byte(s,2) --转为Ascii码,第一个字符是从1开始的而非0
print(s,n) --结果: 01 49
a,b,c = 1,"a" -- 多重赋值
print(a, b, c) -- 1 a nil
a = nil -- nil,回收变量
local multilineString = [[
This is a multiline string.
It can contain multiple lines of text.
No need for escape characters.
]]
print(multilineString) -- 按格式输出括号内字符
This is a multiline string.
It can contain multiple lines of text.
No need for escape characters.
不管定义整形还是浮点型,在Lua中都是number。而没有赋值的变量都是nil。有趣的是,即使赋值了空字符串依然是string类型,看来Lua中nil应当和C差不多,代表了基址未赋值。
Lua 对多个变量同时赋值,不会进行变量传递,仅做值传递:
a, b = 0, 1
a, b = a+1, a+1
print(a,b); --> 1 1而非1 2
顺带一提,Lua语句结束后也可以带分号
其他表示
a = 0x11 -- 16进制表示,16+1=17
b = 2e10 -- 科学计数法,2*(10^10)
c = 5^2 -- 乘方,25
d = 5%2 -- 取余(mod),1
e = 5//2 -- 整除运算,2 (>=lua5.3)
f = 1<<3 -- 移位符号(>=lua5.3),二进制表示下移位:1 = 00000001左移三位(000)00001000 = 8
a,b = "abc","def"
c= a..b --字符串连接,"abcdef"
print(#c) --#输出变量长度(可以是字符串或者表),6
-- 其他语法例如tostring(number),tonumber(string)都是很常规的
n = tonumber("a") --nil,需要注意的是lua和cpp不同,单个字符也不会转为ASCII码
Lua语法
判断
逻辑判断(Lua很特殊,这个比较重要)
Lua认为false和nil为假,true和非nil为真,所以0代表也是真。
唯一需要注意的是Lua中不等于为 ~=
与或非分别是 and or not
让我们看看下面的例子:
a = nil -- false
b = 0 -- true
print(a and b)
print(a or b)
print(not a)nil
0
true
可以看到,在Lua中常规的逻辑判断并不会返回True或者False,只有在not判断下才会返回True和False,而and和or只会返回逻辑值对应的变量的值
再举个例子让我们更好理解
(例如a=nil,值对应false,所以a and b 返回了nil。而b=0 值对应True,a or b返回了0)
a = nil -- false
d = false -- falseB = 0 -- true
C = 1 -- true
and时一真一假输出结果是false的一方
print(a and C) --逻辑判断值返回了逻辑符号左右值中的对应真值和假值
print(C and d)
or时一真一假输出结果是true的一方
print(a or C)
print(C or d)结果:
nil
false1
1
上述例子是正常计算都可以得出的,现在让我们看几个特殊例子
以下例子请抛弃依次执行语句的程序思维,使用更逻辑化,更符合计算机的思维来判断
a = nil -- false
d = false -- falseB = 0 -- true
C = 1 -- true
and时两侧都是真值,则返回右侧的值
print(B and C)
print(C and B)
and时两侧都是假值,则返回左侧的值
print(a and d)
print(d and a)
结果:
1
0nil
falseor时两侧都是真值,则返回左侧的值
print(B or C)
print(C or B)
or时两侧都是真值,则返回右侧的值
print(d or a)
print(a or d)结果:
0
1nil
false
为什么是这样的?也许从程序的思维来看,我们需要执行语句,然后判断。但是实现一个逻辑门判断,有时只需要逻辑符号和其中一个值就够了
接下来用T代表真,F代表假,?代表任意bool
print(F and ?)
在进行and运算的时候,如果第一个值就为false,那输出值一定为false,?是什么都不影响了,所以结果一定为false,输出F即可
print(T and ?)
在进行and运算的时候,如果第一个值为true,我们依然无法确定输出值,此时我们需要知道?是true还是false
但是最后的运算结果一定是由?决定的,如果?为true运算就是true,问号为false运算就是false,所以and左值为真时,输出的结果一定是右值
因此该语句会输出 ?
print(T or ?)
同理,or运算中如果左值为true,结果一定为true,因此输出T即可
print(F or ?)
or运算中如果左值为false,最后结果则是由?是true还是false决定,因此输出结果一定是右值
上述语句输出 ? 现在再回头看看刚才的例子,是不是能理解了?
短路判断
基于上述的原理我们可以进行短路判断
a = nil -- false
b = 0 -- true
print(b > 10 and "yes" or "no")输出:
no所以所谓短路判断,前面应当是正常的判断语句,最后加上and A or B,其中AB都是true值
【T and A or B = A, F and A or B =B】
当前面为真则输出A,当前面为假则输出B
if
if(0)
thenprint("0 为 true")
end
if else
a = 100;
if( a < 20 )
thenprint("a 小于 20" )
elseprint("a 大于 20" )
end
print("a 的值为 :", a) --a 大于 20 --a 的值为 : 100
循环
while
break 关键字是通用是
while( a < 20 )
doa = a+1
end
for
for i=1,10,2 do --- 三个值依次代表起始,结束,步长,步长不输入默认为1print(i)
end
repeat
a = 10
repeat -- 不同与while for,repeat在循环结束时判断,类似do whileprint("a的值为:", a) --输出10,11,12,13,14,15a = a + 1
until( a > 15 ) --当a=16时退出
最重要的知识点就是if,while,for,function都别忘了加end
迭代器
泛型for迭代器
迭代器类似C#的for each,python的for in
array = {"Google", "Runoob"}for key,value in ipairs(array) -- key,value自定义常量名,ipairs(array)迭代列表
doprint(key, value)
end1 Google
2 Runoob
无状态迭代器
function square(iteratorMaxCount,currentNumber)if currentNumber<iteratorMaxCountthencurrentNumber = currentNumber+1return currentNumber, currentNumber*currentNumberend
end
--定义了一个方法square实现循环三次后结束for i,n in square,3,0 --square,3,0代表了迭代方法和它的两个入参,当方法结束主动闭包
doprint(i,n)
end1 1
2 4
3 9
多状态的迭代器
如果迭代函数需要接收很多信息,为了简化迭代函数的入参,不妨将所有的状态信息封装到 table 内,将 table 作为迭代器的状态常量,因为这种情况下可以将所有的信息存放在 table 内,所以迭代函数通常不需要第二个参数。
array = {"Google", "Runoob"}function elementIterator (collection)local index = 0local count = #collection-- 闭包函数return function ()index = index + 1if index <= countthen-- 返回迭代器的当前元素return collection[index]endend
endfor element in elementIterator(array)
doprint(element)
endGoogle
Runoob
需要注意:无论定义什么函数,最后都需要该函数return给迭代变量,才能在迭代器中最终输出对应的值
Lua函数
几个简单的例子,一步到位
----------------------
function f() --同样未用local声明,该函数为全局函数a,b=1,2 -- 函数内定义没有local声明也是全局变量print(a,b)
endf() -- 1 2
--------------------
local function f(a,b,n) --local声明后为局部函数c, d = a, bprint(c, d,n)
end
f(1,2) -- 1 2 nil
-------多返回值--------------------
function f(a,b,c)return a,b,c
end
local i,j =f(1,2)
print(i,j) -- 1 2
--------可变参数---------------
function average(...) --使用...可以接收任意多参数result = 0local arg={...} --> arg 为一个table,局部变量for i,v in ipairs(arg) do result = result + vendprint("总共传入 " .. #arg .. " 个数")print("总共传入 " .. select("#",...) .. " 个数") --select("#",...)来获取可变参数的数量,和直接#arg功能是一样的return result/#arg
endprint("平均值为",average(10,5,3,4,5,6))
---总共传入 6 个数
---总共传入 6 个数
---平均值为 5.5
-----------
function average(a,...) --也可以用固定参数+可变参数,但是固定参数一定放在可变参数之前
end
------------------------
select方法
通常在遍历变长参数的时候只需要使用 {…},然而变长参数可能会包含一些 nil,那么就可以用 select 函数来访问变长参数了:select(‘#’, …) 或者 select(n, …)
select(‘#’, …) 返回可变参数的长度。
select(n, …) 用于返回从起点 n 开始到结束位置的所有参数列表。
调用 select 时,必须传入一个固定实参 selector(选择开关) 和一系列变长参数。如果 selector 为数字 n,那么 select 返回参数列表中从索引 n 开始到结束位置的所有参数列表,否则只能为字符串 #,这样 select 返回变长参数的总数。
function cal_sum(...)a,b =select(3,...)print(select(3, ...))print(select("#",...) )
end
cal_sum(1,2,3,nil,5,5)
print(a,b)3 nil 5 5
6
3 nil使用select赋值会对变量顺序赋值,而select本身可以获取序号及其后的所有可变参数
数组
Lua中没有传统意义的单一类型的数据结构,只有一种table结构,它能顺序存放里面的所有值,并提供了索引以供访问。
需要注意的是,索引是从 1 开始而非传统的0
function P ()return 1;
end
a={1,"ac",{},function() end,P}
print(a[3])
print(a[4])
print(a[5])
print(#a)
a[6] = 1223;
print(a[6])
print(#a)结果:
table: 00BCA580
function: 00BCCAC8
function: 00BCCC48
5
1223
6
我们发现上述table存储了好多奇怪的值,其中包括number,string,table甚至两个function。
通过输出结果我们发现,对于常见的变量类型,table索引可以直接返回值。而对于table function等非常规类型则返回了存储类型+存储地址。
-- insert用法,没有返回值
table.insert(a, "d") --插入到尾部
print(a[7])
s = table.insert(a, 2, 233) --插入到位置2,其后的元素都会后移一位
print(s)
print(a[2])d
nil
233
-- remove会有返回值
s = table.remove(a, 1)
print(s)
print(a[1])1
ac
字符索引
table可以以字符作为索引:
a = {a = 1,b = "1234",c = function()end,d=123456,["!?"] =123
}
a["abc"]="abc"
print(a["a"])
print(a.a)
print(a["!?"]) -- 这只是个例子,别用奇怪的符号命名
-- print(a.!?) --打印不了的,符号会报错
print(a.abc)
print(a.def) --没有这个下标1
1
123
abc
nil
不难发现其实table内是以键值对形式存储的
_G
_G是一个全局table,它储存了所有的全局变量,我们可以通过它来访问任意全局变量
a = 1
b = 2
print(_G["a"])
print(_G.b)1
2
如果上面的还能理解,以下特性简直就是奇葩了
之前我们往tableA里不是使用table.insert插入了一个值吗?让我们看看怎么实现的table.insert(table, 1, "aa")
- lua内有一个全局变量,它的名字就叫table,它的类型是table
- 我们可以直接使用table.insert的原因其实是直接访问了这个名称为table的table的一个字符串索引
- 这个字符串索引的名称是"insert",这个索引对应的值是一个function
- 这个函数实现了往指定table的指定位置插入指定值的功能
print(table[1])
print(_G["table"]["insert"])输出:
aa
function: 00CE8B48
结束语:别忘了
end
相关文章:

【Lua学习笔记】Lua入门
文章目录 Lua变量数据类型变量声明其他表示 Lua语法判断逻辑判断(Lua很特殊,这个比较重要)短路判断 ifif else 循环whileforrepeat 迭代器泛型for迭代器无状态迭代器多状态的迭代器 Lua函数select方法 数组字符索引_G (不是教程&a…...

LLM Data Pipelines: 解析大语言模型训练数据集处理的复杂流程
编者按:在训练大语言模型的过程中,构建高质量的训练数据集是非常关键的一步,但关于构建大模型训练所需数据集的通用数据处理流程(Data pipelines)的相关资料极为稀少。 本文主要介绍了基于Common Crawl数据集的数据处理流程。首先,文章概述了…...

如何使用postman判断返回结果是否正确
针对一个接口,我们在知道参数以及参数对应的结果时,可以通过postman进行判断,验证返回数据是否与预期数据相等。这样可以使我们的接口测试更加的方便简洁。 1、准备数据。 postman可以接受的文件格式如图所示,一般来说可以将我们…...
A General framework for Prompt
你已经知道了 Prompt 可以具有一些通用的结构,比如一个简单的Prompt 结构: 能否帮我为我的课程 TAI自动化,设计一套数字营销策略? Action 我们的目标是激发目标受众一一那些希望利用人工智能简化工作流的人们的兴趣,并提高课程的知名度。 G…...
使用python将PDF转word
实现功能,将程序所在当前路径下的所有PDF文件转化为word import os from pdf2docx import Converter# 获取当前路径 current_path os.getcwd()# 遍历当前路径下的所有文件和文件夹 for file_name in os.listdir(current_path):# 检查文件是否为 PDF 文件if file_n…...

CMU 15-445 -- Logging Schemes - 17
CMU 15-445 -- Logging Schemes - 17 引言IndexFailure ClassificationTransaction FailuresSystem FailuresStorage Media Failures Buffer Pool PoliciesShadow Paging: No-Steal ForceWrite-Ahead Log (WAL): Steal No-ForceLogging SchemesCheckpoints小结 引言 本系列为…...
逻辑回归分析实战(根据鸢尾花的性质预测鸢尾花类别)
紧接着上过一个线性回归模型(一元线性回归模型实战) 一元线性回归模型和逻辑回归模型是统计学中常见的两种回归模型,它们有以下几点不同之处: 1. 目标变量类型:一元线性回归模型适用于连续型目标变量,即预测…...

【每日一题】2050. 并行课程 III
【每日一题】2050. 并行课程 III 2050. 并行课程 III题目描述解题思路 2050. 并行课程 III 题目描述 给你一个整数 n ,表示有 n 节课,课程编号从 1 到 n 。同时给你一个二维整数数组 relations ,其中 relations[j] [prevCoursej, nextCour…...
【kubernetes系列】kubernetes之使用kubeadm搭建高可用集群
概述 目前来说,kubernetes集群搭建的方式很多,选择一个稳定的适合自己的很重要。目前使用kubeadm方式搭建k8s集群还是很常见的,使用kubeadm搭建可以很简单差不多两条命令就行,也可以稍微复杂一点做一些基础优化,本文将…...
SpringBoot 快速实现 IP 地址解析
在spring boot 项目中获取请求的ip与详细地址,很多网站app 中都已经新增了ip 地址显示,大家也可以用在自己的开发中,显得更高级。 引入 如果使用本地ip 解析的话,我们将会借助ip2region,该项目维护了一份较为详细的本…...

【云原生】Docker镜像的创建,Dockerfile
一、Docker镜像的创建 创建镜像有三种方法,分别为【基于已有镜像创建】、【基于本地模板创建】以及【基于Dockerfile创建】。 1.基于现有镜像创建 (1)首先启动一个镜像,在容器里做修改docker run -it --name web centos:7 /bin/…...

了解Unity编辑器之组件篇Event(七)
Event:用于在对象之间进行通信和交互的机制。它可以帮助你实现触发和响应特定动作或状态的逻辑一、Event System:用于处理 UI 事件的系统组件 First Selected 属性:定义了在场景加载或 UI 激活时,哪个 UI 元素将成为首选的选中元素…...
bash: 睡觉的冒号;是不是两个点?
文章目录 简介躺着的冒号是两个点正常冒号总结简介 在bash里冒号和躺着的冒号的用法不一样一定要注意别用错。 躺着的冒号是两个点 难道正常的不是两个点)的作用: A sequence expression takes the form {x…y[…incr]}, where x and y are either integers or single cha…...

揭秘爱数AnyShare认知助手:大模型深度产品化,深化人与机器的“分工协作”
文 | 智能相对论 作者 | 叶远风 大模型竞逐日趋白热化,百模大战热闹非凡。 但是,对产业主体或者普通看客而言,大模型究竟如何改变一线业务、实现工作方式的变革甚至组织转型,很多人并没有具象化的认知。 技术厉害、产品牛&…...
ad+硬件每日学习十个知识点(10)23.7.21
文章目录 1.verilog新建文件夹结构2.怎么在quartus2里新建工程?3.如果在quartus2新建工程后,发现器件选择错误,怎么修改?4.在quartus2新建工程后,怎么新建文件编写程序?4.在quartus2新建工程后,怎么添加已有文件编写程序?5.quartus2怎么调节字体?6.刚下载完quartus2的…...

RCU 使用及机制源码的一些分析
》内核新视界文章汇总《 文章目录 1 介绍2 使用方法2.1 经典 RCU2.2 不可抢占RCU2.3 加速版不可抢占RCU2.4 链表操作的RCU版本2.5 slab 缓存支持RCU 3 源码与实现机制的简单分析3.1 数据结构3.2 不可抢占RCU3.3 加速版不可抢占RCU3.4 可抢占RCU3.5 报告禁止状态3.6 宽限期的开…...

【第二套】Java面试题
第二套: 一、JavaScript前端开发 1、下列的代码输出什么? var y 1; if(function f(){}){y typeof f; } console.log(y);正确的答案应该是 1undefined。 JavaScript中if语句求值其实使用eval函数,eval(function f(){}) 返回 function f()…...

CSS3 实现边框圆角渐变色渐变文字效果
.boder-txt {width: 80px;height: 30px; line-height: 30px;padding: 5px;text-align: center;border-radius: 10px;border: 6rpx solid transparent;background-clip: padding-box, border-box;background-origin: padding-box, border-box;/*第一个linear-gradient表示内填充…...

第二天 kali代理配置
文章目录 环境一、虚拟机网络模式(1)NAT(2)NAT模式(3)桥接模式(4)仅主机模式(5)总结 二、配置代理(桥接模式)1、基础设置2、虚拟机浏览…...

stable-diffusion-webui汉化教程
第一种方法 1.打开stable diffusion webui,进入"Extensions"选项卡 2.点击"Install from URL" 3、注意"URL for extension’s git repository"下方的输入框 4、填入地址:https://github.com/VinsonLaro/stable-diffus…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...

【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态
前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...
用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法
用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法 大家好,我是Echo_Wish。最近刷短视频、看直播,有没有发现,越来越多的应用都开始“懂你”了——它们能感知你的情绪,推荐更合适的内容,甚至帮客服识别用户情绪,提升服务体验。这背后,神经网络在悄悄发力,撑起…...

Qwen系列之Qwen3解读:最强开源模型的细节拆解
文章目录 1.1分钟快览2.模型架构2.1.Dense模型2.2.MoE模型 3.预训练阶段3.1.数据3.2.训练3.3.评估 4.后训练阶段S1: 长链思维冷启动S2: 推理强化学习S3: 思考模式融合S4: 通用强化学习 5.全家桶中的小模型训练评估评估数据集评估细节评估效果弱智评估和民间Arena 分析展望 如果…...