【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…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...
OD 算法题 B卷【正整数到Excel编号之间的转换】
文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...
