需要先保存好文件才能运行文件。
需要先保存好文件才能运行文件。
Lua的一些基础常识
1.nil 空,和C#的null类似但又不同
对于全局变量和table,nil还有删除的作用,给全局变量或table表里的变量赋一个nil值,等同于把他们删掉(同时释放了内存)
nil作比较时要加上引号“”
2.Lua默认只有number一种数字类型
3.string字符串一旦赋值,就不能被修改,可以通过string.gsub()方法来修改,可以写成单引号,但是建议用双引号
当两个全是数字的字符串相加,或一个是数字一个是数字字符串时,字符串会进行类型转换,直接相加
"2" + 1 = "3" "3" + "2" = "5"
如果想连接字符串,就使用 .. 符号代替:“a”..“b”="ab"
#号可以计算字符串长度:(#“www.baidu.com”)= 13
4.常见基本语法
~= 相当于C#中的 !=
and,or,not 对应&&,||,!
局部变量,使用local修饰声明,内存在栈上,在一个函数,代码块{}内,代码块结束,内存自动释放
全局变量在堆上 ,可以随时创建,程序结束,内存自动释放
C#:public void test(){}'; Lua: function test() end
lua没有大括号{},控制语句都是 then ... end
lua没有switch结构 print()会默认换行
只有nil是false,0和1都是true
4.table(表)
table可以有数组形式,字典形式,数组字典同时混合形式
5.元表
元表可以扩展普通表的行为,普通表无法直接加减运算等,但可以用元表扩展各类功能
当使用getmetatable方法获取普通表的元表时,如果元表中含有(双下划线)__metatable键值,操作会失败,只能获取到对应的值,不能获取其他东西,用此方法可以保护已经写好的元表扩展不能被其他人获取
__index,元表的扩展方法,当访问到一个不存在的索引的时候,调用这个方法,这个方法默认返回nil
可以直接给__index 赋值一个其他的表,系统会自动寻找这个表有没有对应的值,如果有就返回,没有还是默认的nil
也可以给__index赋值一个方法,用来进行其他操作,比如直接返回设置好的变量之类的
__newindex:当我们对表的数据进行修改的时候,当我们修改的是一个新的索引的时候,也就是之前没有的索引的时候,自动调用
当修改的是一个已经存在的数据的话,不会起作用
(当我们给表添加新的键值对的时候,会调用此方法)
当__newindex 后面是函数的话,会调用此函数,如果后面跟了一个其他的表,那么会将此键值对赋值给那个表,原来的表没有变化
__add:当对两个表进行相加操作时,会起作用,并执行方法,具体结果和写的方法有关
多行注释用
--[[ 比--[[
--]] ]]
好因为只要在第一段多打一个-,这样被注释掉的东西就可以用了。
---[[
--]]
lua 数据类型
nil 空类型,表示一个无效的值
boolean true/false
number 数字类型(int+double)
string 字符串类型
function 函数
userdata 用户数据类型,表示存储在变量中的C数据类型
thread 协程(异步执行,与线程不同)
table 表类型,关联数组,通过构造表达式。可以实现类
type(变量) 返回变量的类型
lua 和 c# 编程的区别
lua轻量小巧,直接写
c#:
class A{
public static void main(string[] args){
}
}
全局变量
默认总是全局的,不需要声明
nil == null
删除变量 a = nil
标识符
规则:
不推荐下划线+大写字母(保留字格式,lua内部全局变量)
适当笔记 多写代码
print("")打印函数,输出字符串
行间不强制需要加分号
注释:
--
单行注释
--[[
--]]
多行注释
取消注释
---[[
--]]
Lua函数的声明
使用关键字function
function fact(n)
if n == 1 then
return n
else
return n*fact(n-1)
end
end
print(fact(2))
print(fact(5))
fact2 = fact
print(fact2(5))
Lua变量不建议使用_加大写字母
严格区分大小写
Root 和 root是两个不同的变量
for(int i=0,i<10,i++)
lua中的变量是可以随时变化类型的
local是局部变量关键字
使用vs code来配置开发环境,比这个scite好用
thread
userdata
当通过冒号调用的时候,系统会自动传递当前的table給self;
当通过点来调用方法的时候,self不会子哦对那个复制,我们必须通过第一个参数来传递当前的table
coroutine.status() 获取一个协同程序的运行状态,需要传入你要获取的协同程序,返回值是一个字符串
协同程序只能执行一次(执行完成之后就会处于死亡(dead)状态)
如果使用coroutine.create()创建的协同程序
第二次启动的时候不会报错,但是也不会再次执行
如果使用coroutine.wrap()创建的协同程序
第二次调用的时候会报错提示这个协同程序已经处于死亡(dead)状态
coroutine.running() 获取一个正在运行的协同程序,返回值是一个协同程序的线程号(一般只有把这个方法写到你要获取的那个协同程序里面才能获取成功)
如果一个协同程序有参数,中间有暂停,当你在暂停之后再次启动这个协同的程序的时候可以不用传参数,只需要传这个协同程序(他会使用上次启动时所传的参数执行),如果你传递参数这个参数会作为上次coroutone.yield()的参数
协同程序的返回值会返回协同程序执行的结果(true和false)
如果有其他返回值,后面的返回值才是你所返回的返回信息
如果想在协同程序暂停的时候返回信息,可以在coroutine.yield()的括号里面写上要返回的信息
co = coroutine.wrap(
function()
end
)
定义一个co协同程序
co()
启动co协同程序(这种创建协同程序的启动方法和调用普通的function一样,但是不能暂停)
co = coroutine.create(
function()
coroutine.yield()
end
)
定义一个co协同程序
coroutine.resume(co)
启动co协同程序(执行到coroutine.yield()的时候会停止运行)
coroutine.resume(co)
继续启动co协同程序(从coroutine.yield()开始继续往下执行,如果有参数继续执行的时候可以不传参数)
co = coroutune.create(
function()
end
)
定义一个协同程序co
coroutine.resume(co,协同里面function里面的参数(没有参数可以不写))
启动协同函数(不启动,不会执行)
table.sort(mytable) 把mytable表中的元素进行排序(按照ASCII值进行排序)