您的位置:首页 > 编程语言 > Lua

一看就会的Lua笔记(全中文)

2020-03-05 10:13 603 查看
【注意事项】
--在任何地方声明的变量都是全局变量,当要销毁(排泄)时,就设置为nil或null
--在lua中,所有索引以1开始
--使用#井号可以计算出字符串的长度,唯独中文字符要占用两个长度
--用#也可以获得table的最大索引
--函数可以用于数据赋值,可以用作参数传递;而且函数可以用多个返回值
--用两个等号==表示相等,用~=表示不相等
--用and表示条件都满足时返回真,用or表示任意满足时就返回真
--在boolean前加not是逻辑非操作符,会变成与逻辑运算结果相反的结果
--字符串可以用""和''和[[]]三种方式定义
--用..连接两个字符串
--函数可以接受可变数目的参数,和 C 语言类似,在函数参数列表中使用 ... 三点表示函数有可变的参数
【注释方法】
--单行注释,两个-单杆
---[[
多行注释
--]]
【使用方法】
require "模块名" --模块的引入
变量名 = require ("模块名") --可以把模块赋值给变量,通过调用变量来调用模块,也可以声明为local

模块名.变量名() --调用变量中存储的函数

function 函数名(参数) --不写函数名可以就是匿名函数

if 表达式 then

print("输出string内容");

elseif (表达式) then

--关于elseif是连起来的,中间没有空格或间隔

eles

函数名(参数); --函数的调用

end --在lua中,用end表示if的结束

do --这do没有特殊效果,通常用作子代码块,语句块

local 变量名 = 值; --变量名前加local是声明局部变量

end

变量,变量,变量 = 值,值,值; --变量批量赋值,值和数据类型都可以不一样

while(表达式)do --循环while

--需要自增让表达式不成立

end

for 变量=值,结束值,增值 do --循环for

--不等于结束值时继续执行,每次执行完毕会增加“增值”

end

for 值,值 in pairs(table表名) do --遍历(table)表,遍历循环,也可以是ipairs

--能输出(table表名)表中的“值(k),值(v)”全部内容

end

repeat --会先执行循环体

--循环体

until(表达式) --满足这个条件后将不再执行,这个条件最少会执行一次+

普通表名 = setmetatable({普通表数据内容},元表) --元表可以扩展普通表的行为

return 返回值; --可以返回多个值(return 返回值,返回值;)

end --在lua中,用end表示函数的结束

变量,变量 = 函数名(参数); --接收时可以只接收一个值(变量 = 函数名(参数);)
thread(线程)
--在 Lua 里,最主要的线程是协同程序(coroutine)。它跟线程(thread)差不多,拥有自己独立的栈、局部变量和指令指针,可以跟其他协同程序共享全局变量和其他大部分东西。

--线程跟协程的区别:线程可以同时多个运行,而协程任意时刻只能运行一个,并且处于运行状态的协程只有被挂起(suspend)时才会暂停。
userdata(自定义类型)
--userdata 是一种用户自定义数据,用于表示一种由应用程序或 C/C++ 语言库所创建的类型,可以将任意 C/C++ 的任意数据类型的数据(通常是 struct 和 指针)存储到 Lua 变量中调用。
【数据类型】
--nil				这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)

--boolean		包含两个值:false和true

--number		表示双精度类型的实浮点数

--string			字符串由一对双引号或单引号来表示

.upper(小写字母)	 --把小写字母转成大写字母

.lower(大写字母)	 --把大写字母转成小写字母

.gsub(字符串,"被替换","替换成") --替换字符串
.gsub(字符串,"被替换","替换成",可替换最大次数)

.find(字符串,"要查找的字符串") --查找字符串,返回查找到位置的索引
.find(字符串,"要查找的字符串",开始查找位置的索引)
.find(字符串,"要查找的字符串",开始查找位置的索引,进行查找后的结束索引)

.reverse(字符串) --字符串反转

.format("%d,%d,%d",变量,变量,变量) --字符串格式化,全部%d内容依次改为变量内容

%c - 接受一个数字, 并将其转化为ASCII码表中对应的字符
%d, %i - 接受一个数字并将其转化为有符号的整数格式
%o - 接受一个数字并将其转化为八进制数格式
%u - 接受一个数字并将其转化为无符号整数格式
%x - 接受一个数字并将其转化为十六进制数格式, 使用小写字母
%X - 接受一个数字并将其转化为十六进制数格式, 使用大写字母
%e - 接受一个数字并将其转化为科学记数法格式, 使用小写字母e
%E - 接受一个数字并将其转化为科学记数法格式, 使用大写字母E
%f - 接受一个数字并将其转化为浮点数格式
%g(%G) - 接受一个数字并将其转化为%e(%E, 对应%G)及%f中较短的一种格式
%q - 接受一个字符串并将其转化为可安全被Lua编译器读入的格式
%s - 接受一个字符串并按照给定的参数格式化该字符串

一个0在后面指定了字串宽度时占位用,要%0Xd表示占用X个字符(占位符)

在指定了字串宽度时,默认为右对齐,增加-号可以改为左对齐(对齐标识)

一个+号表示其后的数字转义符将让正数显示正号,默认情况下只有负数显示符号(符号)

在宽度数值后增加的小数部分n若后接f则设定该浮点数的小数只保留n(浮点数转义符, 如%6.3f)位, 若后接s(字符串转义符, 如%5.3s)则设定该字符串只显示前n位

.char(整数) --整数 ASCII 码转换为字符

.byte(字符串) --将整型数字转成字符并连接
.byte(字符串,指定被转换的字符索引) --索引为整数;可以指定某个字符,默认第一个字符

.len(字符串) --获取字符串长度

.rep(字符串,复制次数) --拷贝字符串,返回值是拷贝(复制次数)次后的字符串

.gmatch(字符串,pattern) //正则表达式,返回迭代器函数;参数pattern描述的字符串没找到,返回空

--function	由 C 或 Lua 编写的函数

--userdata	表示任意存储在变量中的C数据结构

--thread	表示执行的独立线路,用于执行协同程序

--table		Lua中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字、符串或表类型。在Lua里table的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。
使用方法:table{int = 值, string = 值}构建,用table.int访问int的值

.concat(table) --无缝拼接(table连接)
.concat(table,string) --选择拼接的table并指定以string进行分割
.concat(table,string,开始索引,结束索引)

.insert(table,数据) --给table插入“数据”,默认是末尾
.insert(table,指定索引,数据) --是直接插入,并不会删除数据,原数据索引向后移

.remove(table,指定索引) --移除对应索引的数据,能保持上下索引连续

.sort(table) --排序

.maxn(table) --获取最大值
【转义字符】
\n 换行

\\ 代表一个反斜杠

\" 代表"

\" 代表'

--外层使用了单引号或双引号,内层就不使用单引号或双引号;内外层只能是不同引号
【迭代函数】
function 迭代函数(参数列表)

return 返回值;

end

for 变量列表 in 迭代函数, 状态变量, 控制变量 do --迭代函数

--把状态变量和控制变量当做参数传递给迭代函数
--调用迭代函数,状态变量只会在第一次调用的时候赋值
--如果迭代函数返回值为空,退出for循环
--如果不是空,把返回值赋值给变量列表,并执行循环

end

--每次执行,控制变量会增加,满足状态变量时不执行
--迭代函数名必须一致,变量列表和参数列表尽量保持一致
--类似C#中的遍历键值对
【定义模块】
模块table名 = {} --模块table名必须和模块名(脚本命名)一致

模块table名.变量名 --可以存储任何值,包括函数,存储函数可以通过访问变量以调用函数

require 返回值; --可以让调用该模块获得返回值

--模块中可以定义局部local函数,但没办法在模块外被访问;相当于私有变量

setmetatable(普通表,元表) --元表的声明和绑定,把元表设为普通表的元表
setmetatable(普通表,元表)[下标索引] --能返回普通表中对应索引的数据

getmetatable(普通表) --能够获取普通表所对应的元表

setmetatable(普通表,{__metatable}) --设置__metatable可以保护元表,禁止修改和访问
setmetatable(普通表,{__metatable="对应字符串"}) --设置获取元表只能获取对应字符串
--也就是说,无法用“getmetatable”获取元表
--使用setmetatable其返回值是table

元表 = { __index = {索引="内容",索引="内容",索引="内容"} } --当访问不存在的索引,会从表中获取

元表 = {
__index = function(tab,key)
--当访问不存在的键,会调用此方法
--参数key传递不存在的键到方法
--参数tab传递报错的table
--而且可以有返回值,访问不存在的键,可获取该return
end
}

元表 = { __newindex = function或table} --当给表增加新索引的时候,会调用__newindex
--关于__newindex和__index一样,可以是表,也可以是函数

rawset(table,索引,内容) --更新表,在__newindex函数里面更新table时,要用rawset

--如果__newindex是表,添加的索引会添加到__newindex而不是元表

元表 = {
__add = function(tab,newtab)
return 返回值 --进行加法运算后,获得该返回值
end
} --该__add扩展了普通表的行为,任意一个表有该元表即可进行加法操作

__sub --减法操作

__mul --乘法操作

__div --除法操作

__mod --求余操作

__unm --

__concat --对应的运算符 '..'字符串拼接操作

__eq --对应的运算符 '==' 判断是否相等

__lt --对应的运算符 '<'

__le --对应的运算符 '<='

元表 = { __call = function或table} --当把表当函数调用时,就会调用__call
--可以有参数或有多个参数

元表 = { __tostring = function或table} --用于修改表的输出行为,可以自定义了表的输出内容
--输出内容用return返回
【协同程序】
--变量名 = coroutine.创建协同函数(函数) --用create或wrap创建

coroutine.create(函数) --创建coroutine返回coroutine参数是一个函数;协同函数的定义
--当和resume配合使用的时候就唤醒函数调用
--返回值是一个协同函数,需要变量接收,而且需要通过resume来调用启动

coroutine.resume() --重启coroutine和create配合使用;有暂停和继续的功能
coroutine.resume(协同函数,函数的参数,函数的参数) --可以用来调用,暂停,继续
--可以有 return 返回值,返回值,返回值 多个返回值
--变量一,变量二 = coroutine.resume(协同函数,函数的参数,函数的参数)
--使用resume的第一个返回值是boolean类型,第二个才是自定义返回值
--如果resume启动失败,第一个返回值是false

coroutine.wrap() --创建coroutine返回一个函数,一旦你调用这个函数,就进入coroutine和create功能重复
--和create一样用于创建协同函数,与众不同的是wrap可以直接调用
--返回值是一个协同函数,需要变量接收

coroutine.yield() --挂起coroutine,将coroutine设置为挂起状态,这个和resume配合使用能有很多有用的效果
--在协同函数方法体内增加coroutine.yield()可使代码运行到yield()时起到暂停运行的效果
--但协同函数方法体外的代码依然会继续运行
--当使用coroutine.resume()调用时,协同函数会继续未运行完的部分
--二次运行时resume可以不传递参数
--暂停时,返回的第一个返回值是true执行成功,自定义返回值为nil
--暂停时需要有自定义返回值,可以在yield中传递参数yield(参数,参数)当返回值返回

coroutine.status() --查看(获取)coroutine的状态
--关于coroutine的状态有三种:dead/suspended/running
--其中suspended是暂停的
--其中running是正在运行
--其中dead是运行完的,协同运行完后就是dead
【文件读写】
--简单读取:先用open获取要读取的文件,用input读取,用read读取文件内容,最后用close关闭文件

--变量名 = io.open (文件名.扩展名, 模式) --用变量接收读取文件
--文件是以能否被记事本(.txt)打开的方式打开的

io.open (文件名, 模式) --打开文件。可以定义变量接收,读取文件有模式如下
--r 以只读方式打开文件,该文件必须存在
--w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件
--a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)r+	以可读写方式打开文件,该文件必须存在。
--w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件
--a+ 与a类似,但此文件可读可写
--b 二进制模式,如果文件是二进制文件,可以加上b
--+ 号表示对文件既可以读也可以写

io.input(接收到读取文件的变量) --设置默认输入文件。指定要读取的文件
--准确的说应该是“接收到打开文件的变量”

io.read() --读取文件内容,读取前需要用input指定要读取的文件,返回值是字符串
--该函数是调用一次读取一行,读取不到内容时返回nil空
--可以不带参数,带参数可以是下表中的一个:
-- "*n"读取一个数字并返回它。例:file.read("*n")
-- "*a"从当前位置读取整个文件。例:file.read("*a")
-- "*l"(默认)读取下一行,在文件尾 (EOF) 处返回 nil。例:file.read("*l")
-- number返回一个指定字符个数的字符串,或在 EOF 时返回 nil。例:file.read(整数)

io.close(接收到读取文件的变量) --文件关闭。关闭open打开的文件

--简单写入:先用open获取打开的文件,用output设置要写入的文件,用write写入内容,用close关闭打开的文件

io.output(接收到打开文件的变量) --设置默认输出文件。指定要写入的文件

io.write("写入的内容") --写入内容到文件,写入前需要用output指定要写入的文件
--写入的内容可以用\n等转义字符

--完全模式:先用io.open获取打开的文件,用变量接收读取到的文件(接收到读取文件的变量)

接收到读取文件的变量:read() --获取文件第一行

接收到读取文件的变量:close() --关闭打开的文件

接收到读取文件的变量:write("内容") --在文件最后一行添加内容

接收到读取文件的变量:seek(模式,指定位置) --设置和获取当前文件读取到的内容位置
-- "set" 从文件头开始
-- "cur" 从当前位置开始[默认]
-- "end" 从文件尾开始
-- offset 指定位置,默认为0

io.tmpfile() --返回一个临时文件句柄,该文件以更新模式打开,程序结束时自动删除

io.type(接收到读取文件的变量) --检测obj是否一个可用的文件句柄

io.flush() --向文件写入缓冲中的所有数据

io.lines() --打开指定的文件并返回一个迭代函数,每次调用能获取一行内容,当到文件尾时返回nil
--该函数不会自动关闭文件
【垃圾回收】
--Lua提供了以下函数collectgarbage([opt [, arg]])用来控制自动内存管理

collectgarbage("collect") --做一次完整的垃圾收集循环。通过参数 opt 它提供了一组不同的功能

collectgarbage("count") --以 K 字节数为单位返回 Lua 使用的总内存数。 这个值有小数部分,所以只需要乘上 1024 就能得到 Lua 使用的准确字节数(除非溢出)

collectgarbage("restart") --重启垃圾收集器的自动运行

collectgarbage("setpause") --将arg设为收集器的 间歇率。返回 间歇率 的前一个值

collectgarbage("setstepmul") --返回 步进倍率 的前一个值

collectgarbage("step") --单步运行垃圾收集器。步长"大小"由arg控制。传入0时,收集器步进(不可分割的)步。传入非0值,收集器收集相当于Lua分配这些多(K字节)内存的工作。如果收集器结束一个循环将返回true

collectgarbage("stop") --停止垃圾收集器的运行。在调用重启前,收集器只会因显式的调用运行
【面向对象】
--通过table实现面向对象,表可以有属性和方法

--table = {属性名 = 数据, 属性名 = 数据}

--table.函数名 = 函数(); --table.函数名 = function(){}end

--通过table.函数名()来调用

function 方法名:表名() --通过:号定义方法,就能通过“表名:方法名”来调用
--在使用:号进行方法的定义和调用时,能以self代表当前表,如self.属性名
end

--使用.号定义方法,也可以通过.号来调用方法

原型 = {属性=数据,属性=数据} --实现通过类去创建多过对象

function 原型方法名:原型
--其实“原型”就是表table
--其实“原型方法名”就是通过:号定义的方法
end

function 原型方法名:new()
表名 = {} --表名前需要加local不然默认全局变量
setmetatable(表名,{__index=self})
--调用一个属性的时候,如果表名中不存在,那么会做__index所指定的table中查找
return 表名;
end

新table名 = 原型方法名:new() --实现通过类去创建多过对象

function 原型方法名:new(参数) --实现构造方法
local 表名 = 参数 or {}
setmetatable(表名,{__index=self})
--调用一个属性的时候,如果表名中不存在,那么会做__index所指定的table中查找
return 表名;
end

新table名 = 原型方法名:new({属性=数据,属性=数据}) --还可以在现有的属性的基础上,增加新属性

新table名 = 原型方法名:new() --实现面向对象的继承

新表名 = 新table名:new() --新表名 继承自 新table名
  • 点赞
  • 收藏
  • 分享
  • 文章举报
ZhUGgLianG 发布了2 篇原创文章 · 获赞 0 · 访问量 74 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: