Lua使用

Lua
在lua中,一切都是变量,除了关键字

优点:

轻量级:它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。
可扩展性:lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些写功能,
支持面向过程编程和函数式编程
自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象
语言内置模式匹配,闭包,函数也可以看作一个值;提供多线程(协同进程,并非操作系统所支持的线程)支持
通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承和重载等

语法

不定参数,跟C#中params object[] arg差不多
function A(…)
local a1 ,a2,a3,a4 = …
end
A(1,2)

注释:

单行注释“–”
多行注释:“–[["开始,”–]]"结束

变量

Lua中的变量全是全局变量,即使在语句块或者函数中,除非用local显示声明为局部变量

变量的默认值默认值均为nil

语法

do+end代表一个作用域,类似{}

if语句语法: if 判断 then 表达式 else if 判断 then end end(一个then 对应一个end)

lua中repeat until循环对应C#中do while循环

基本类型

lua中8个基本类型:
nil,boolean,number,string,userdata,function,thread,table
userdata专门和lua的宿主机(解释器)打交道。userdata可以将C数据存放在lua变量中,userdata在lua中除了赋值和相等比较外没有预定义的操作。userdata用来描述应用程序或者使用C实现的库创建的新类型。例如:用标准I/O库来描述文件

table当作数组使用时,索引是从1开始的,当作哈希时,key要用[]包起来
lua也是通过table来解决模块(module)、包和对象的

运算符

l不等于:~=,
逻辑运算符:and or not,
连接运算符:…(字符串连接,连接符两边必须要有空格)
逻辑运算符认为false和nil是假(false),其他为真
and 和or的运算结果不是true和false,而是和它的两个操作数相关,例如:
a and b :如果a为false,则返回a,否则返回b
a or b:如果a为true,则返回a,否则返回b

补充

幂次方语法:a^b

可以给多个变量赋值,例如:a,b,c,d=1,2,3,4
也可以这样:a,b = b,a;交换变量
while true do end
for i,10,1 do end

方法返回:do return end;

Table(表)

table是lua中唯一的一个数据结构,(自定义数据类型)通过table,我们能扩展出其他的数据结构,比如:数组,类
API:

table.concat(table [,sep[,start[,end]]]):

列出参数中指定table的数组部分从start位置到end位置的所有元素,元素之间以指定的分隔符隔开
例如: a={1,2,3,4,5}
table.concat(a,“x”,2,3); – 2x3

table.insert(table,[pos,] value);

在数组部分指定位置(pos)插入值为value的一个元素,pos可选,默认为数组末尾

table.maxn(table)

指定table中所有正数key值中最大的key值,如果不存在key值为正数的元素,则返回0。(lua5…2)之后该方法不存在

table.remove(table[,pos])

返回table数组部分位于pos位置的元素,其后的元素会被前移,pos参数可选,默认为末尾

table.sort(table[,comp])

对给定的table进行升序排序,comp:函数指针、委托

table.getn(t)

获取表中的长度,#t也可以

遍历

(1) for i,v in ipairs(a) do
end
从索引=1,开始遍历,输出不为空的值,当值为空时,退出这个循环
(2) for key value in pairs(table) do
end
遍历这个table中所有的key和value
(3) for key in pairs(table) do
end
遍历这个table中所有的key

备注

(1) 可以把这个类型看作数组
(2) 可以用任意类型来做数组索引,除了nil
(3) 所有元素之间,总是用“,”隔开
(4) 所有索引值都需要用"[" 和 "]"括起来;如果是字符串还可以去掉引号和中括号
(5) 在构造函数的最后的“,”是可选的,可以方便以后的扩展。如果不写索引,则索引就会被认为是数字,并按顺序自动从1往后编排

函数

当一个函数内部嵌套另一个函数定义时,内部的函数体可以访问外部的函数的局部变量,这种特征我们称为词法定界。很少语言提供这种支持

函数变量:

xp = function (x) return x+1 end

函数和表配合

xpTable = {}
function xpTable.xpF(x)
return x+1
end

函数调用时:和.的区别

冒号的作用就是在定义函数的时候,会给函数添加第一个参数self,调用时,默认会把调用者作为第一个参数传递进去
而.不会传递self,如果要实现冒号的作用,那么在参数的一个为self即可,

系统函数OS

os.clock()–返回当前运行时间
os.time()–返回系统当前时间戳,以秒为单位
os.time({year=12, month = 12, day = 23}), 将日期转成时间戳
os.date(“*t”, timestamp)–将一个时间戳转成日期格式talbe,通过year,month,day,hour,min访问,除了“*t”之外还有
“%a”, 返回一星期中天数的简写(Fri),
“%A”----返回全称
https://blog.csdn.net/w739116149/article/details/88824461

模块与包

模块类似于一个封装库, 从lua5.1开始,lua加入了标准的模块管理机制,可以把一些公用的代码放到一个文件里,以API接口的形式在其他地方调用,有利于代码的重用和降低代码耦合度

模块声明

模块本质也是一个table。最后返回这个table就可以了

模块引入

require函数
Lua提供了一个名为require函数用来加载模块。要加载一个模块,只需要简单的调用就可以了。
例如:require(“<模块名>”)
或者require “<模块名>”
执行require后会返回一个由模块常量或函数组成的table,并且还会定义一个包含该table的全局变量。

对于自定义的模块,模块文件不是放在哪个文件目录都行,函数require有它自己的文件路径加载策略,它会尝试从Lua文件或C程序库中加载模块

require用于搜索Lua文件的路径是存放在全局变量package.path中,当Lua启动后,会以环境变量LUA_PATH的值来初始化这个环境变量。如果没有找到该环境变量,则使用一个编译时定义的默认路径来初始化

元表

在lua table中我们可以访问对应的key来得到value,但是却无法对两个table进行操作。
因此lua提供了元表(Metatable),允许我们改变table的行为,每个行为关联了对应的元方法。
例如可以用在两个表相加。会先检查两个表之间是否有元表,在检查是否有_add字段,如果有,则调用对应的值。_add对应的值往往是一个函数或者table,就是元方法
两个函数处理元表
setmetatalbe(table,metatable):对指定table设置元表(metatable),如果元表中存在_metatable键值,setmetatable会失败
getmetatable(table):返回对象的元表

元方法

__add 对应的运算符 ‘+’.
__sub 对应的运算符 ‘-’.
__mul 对应的运算符 ‘*’.
__div 对应的运算符 ‘/’.
__mod 对应的运算符 ‘%’.
__unm 对应的运算符 ‘-’.
__concat 对应的运算符 ‘…’.
__eq 对应的运算符 ‘==’.
__lt 对应的运算符 ‘<’.
__le 对应的运算符 ‘<=’.

__index:

当你通过键来访问table的时候,如果这个键没有值,那么就会寻找table的metatable(如果有的话)中的__index键。
如果__index包含一个表格,Lua会在表格中查找相应的键。(感觉跟继承好像)
如果__index包含一个函数的话,Lua就会调用那个函数,table和键会作为参数传递给函数。
Lua查找元素规则:
1,在表中找,有的话就直接返回,没有则判断是否有元表,没有返回nil。有的话则判断元表有没有__index方法,
如果__index方法为nil,返回nil;
如果__index是一个表,则重复以上的操作;
如果_index是一个函数,则返回该函数的返回值

__newindex

__newindex用来对表更新,__index用来对表访问,__index会修改原表,而__newindex不会修改原表,只会修改原表所对应的元表里的__newindex表
当你给表的一个缺失的索引赋值,解释器就会查找__newindex元方法:如果存在则调用这个函数而不进行赋值操作

如果想给__newindex的原表进行增加键值,通过rawset方法
__newindex=function(table,key,value)
rawset(mytable,key,“”" … value … “”")
end

__call

__call元方法在Lua调用一个值时调用

__tostring

用于修改表的输出行为,跟重写C#ToString方法一样

例如:__add

协同程序

Lua协同程序(coroutine)与线程类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西,

coroutine.create(函数):创建携程并返回携程,参数是一个函数,当和resume配合使用的时候就唤醒函数调用
coroutine.resume(携程,携程里的函数参数列表):重启携程,和create配合使用
coroutine.yield([返回值]):挂起携程,如果有返回值,返回这个返回值,和resume配合使用
coroutine.wait(时间):暂停携程多少秒
coroutine.status(携程):查看携程的状态,dead,suspend,running三种状态
coroutine.wrap(函数):创建携程,返回一个函数,一旦调用这个函数,就开启携程
coroutine.running():返回正在运行的携程,返回的是携程的ID号

I/O读取和处理文件

分为简单模式(和C一样)、完全模式
简单模式:拥有一个当前输入文件和一个当前输出文件,并且提供针对这些文件相关的操作
完全模式:使用外部的文件句柄来实现。它以一种面向对象的形式,将所有的文件操作定义为文件句柄的方法

简单模式操作

打开文件

file = io.open(filename[,mode])
mode的值:

r 以只读方式打开文件,该文件必须存在。
w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
r+ 以可读写方式打开文件,该文件必须存在。
w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
a+ 与a类似,但此文件可读可写
b 二进制模式,如果文件是二进制文件,可以加上b

  • 号表示对文件既可以读也可以写

输入文件

io.input(file):设置默认输入文件,参数为文件对象

输出文件

io.output(file):设置默认的输出文件

读取文件

io.read():读取文件的最后一行
io.read(“*n”):读取一个数字并返回它
io.read(“*I”)读取下一行,在文件尾返回nil
io.read(number):返回一个指定字符个数的字符串

写入文件

io.write(“ssss”):在最后一行写入

关闭文件

io.close(file):关闭打开的文件

保存文件

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

遍历文件每行数据

io.lines(filename):返回一个迭代函数,

完全模式操作

用来同时操作多个文件。需要使用file:function_name来代替io.function_name

设置和获取当前文件位置

file:seek(optional whence,optional offset):设置和获取当前文件位置,成功返回最终的文件位置(按字节),失败则返回nil。
whence值:
“set":从文件头开始
“cur”:从当前位置开始(默认)
“end”:从文件尾开始
offset:默认为0

垃圾回收

只要无任何引用这个变量,就会被定时的清理

● 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中提供一个new方法,
Shape = {area = 0}
function Shape:new (o)
o = o or {}//nil判断
setmetatable(o, self)
self.__index = self
return o
end

继承

Son = Shape::new({子类独有的})
子类对象:s =Son:new()

猜你喜欢

转载自blog.csdn.net/weixin_44806700/article/details/122347741