Lua是一门语言,我们可以使用一个库,可以在运行时去编译执行Lua中的代码,从而实现自己的内存中的数据和逻辑;

准备学习环境:

新建一个Lua项目目录,用来写我们的Lua代码;
进入目录,右键使用vsCode打开 或者,先打开vsCode,然后 文件->打开文件夹 ,选择我们的项目目录;

为vsCode安装Lua相关的插件Lua(Lua Language Server coded by Lua)LuaDebug插件

执行Lua

按Ctrl + J,打开控制台,输入命令:Lua 文件名.Lua

local:

代表变量,只能在当前chunk(块)中访问到

不加local的变量:

代表变量,默认情况下是全局可以访问

数字 :整数和浮点数 都是number类型

函数:

重点是得理解,函数的定义,和函数的执行 是两码事
定义,只是在内存中生成了这个函数对象
执行,才是真正去执行函数中代码

块(Chunk)

可以认为是是一个局部的环境;一个函数就是一个块,一个Lua脚本(模块)就是一个块;do .. end 也是一个块
local 只能在当前块中访问

访问的变量不存在时,不会报错,而是把这个变量当前nil处理

表:

可以把表当成一个容器,这个容器由两部分组成,字典和list
表里可以放任何东西
没有键的数据,会放到list中,有键的放到字典中;key,可以是任何类型除了nil以外
如果key是数字必须 这样写:t={[3]=4}
Lua中,数组是从1开始索引的,不是从0开始的

遍历表

使用ipairs遍历 数组部分
数组部分的元素会被nil截断;ipairs会无法遍历nil以后的数据
#可以获取数组的长度,但是如果倒数第二个索引为nil,那么#就不会获取最后这两个数据的长度了
所以,不要使用nil来删除数组中的元素
使用table库来操作表
使用pairs遍历 所有数据
字典部分,如果值为nil,就相当于删除了这个数据
访问一个变量时,先查询 当前块中的局部变量,如果查询 不到,会查询 上一级(upValue)中的该变量,依次类推,直到查询到全局变量为止;
Lua中没有+=
使用~= 代替!=
使用 not and or 代替 && ||
先计算not再计算and,最后是or
在Lua中,false和nil,都当作false做逻辑运算
io.read(获取键盘输入)和多重返回值

数据类型:

在Lua中,只有table和字符串,是引用类型;
number是双精度的实浮点型

闭包:

当一个内部函数,引用了外部函数的一个局部变量时,那么就会形成闭包;
因为这个局部变量,不会再被外界访问到;只有该函数自己可以访问;
可以理解为,每个函数对象定义时,会有一个上值(环境表),这个上值中,会储存这个函数所引用的数据;

元表:

Lua中每个对象都可以有个元表,也可以没有;我们现在关注表的元表就可以了;
setmetatable(设置元表)
getmetatable(访问元表)
可以使用t.name直接访问表t中name的key,不需要 t[“name”]

元方法:

在元表中方法,以__开头的方法,都是元方法
元方法,是Lua内置定义的名字,你不能自己定义
__index:当你访问一个表t1不存在的key时,会查询 t1的元表t2中的__index指向的方法
__newindex:当你写入一个表t1不存在的key时,会调用t1的元表t2中的__newindex指向的方法

模块:

在Lua中,一个Lua文件对应的块,就是模块
可以使用require去加载模块到内存中
require返回的是模块最后return的结果,默认返回true
require一个模块多次,模块中的代码,只会执行一次,并且会返回之前require的结果
local只能在当前块中访问,模块也是一个块儿
总是需要一个入口模块来启动Lua,有点像我们C#中的Main函数的作用

面向对象

使全局变量定义一个对象,并且在方法内部使用这个全局变量引用这个变量,会造成强关联
我们可以定义方法时,将对象本身作为第一个参数传入,在函数内部使用这个参数去操作对象

语法糖

function Account:WithWindow1(v)  self.balance = self.balance - vend

当给一个表使用冒号定义一个方法时,相当于自动为该方法添加了一个self作为形参

Account:WithWindow1(100)

当一个表使用冒号来调用一个方法时,相当于把自己作为第一个参数,传到方法中使用

对象将元表设为自己的类表,类表的index指向本类表;那么将来访问对象的方法时,就会访问到这个类表中的方法

静态方法

当类表作为调用者时,这个方法就是静态的方法,静态方法和实例方法在表示上没有区别