Lua脚本教程
- 一、数据类型
- 1、常量、变量
- 2、变量名:字母、数字、下划线(不能以数字开头)
- 3、几种数据类型
- 二、运算符
- 三、初识函数
- 四、判断语句
- 五、循环语句
- 六、表
- 七、高级函数与控制结构
- 八、函数库
- 1.基本库
- 2.数学库,表库
- 3.字符串库
- 4.操作系统库
- 5、流和文件库
一、数据类型
1、常量、变量
a=10
a=2.5
a=“abcd”
左边是变量、右边是常量
lua中注释符是 –
2、变量名:字母、数字、下划线(不能以数字开头)
内置关键字:
and | break | do | else | elseif | if | or |
end | in | false | ture | function | not | local |
while | repeat | nil | then | return | for | until |
3、几种数据类型
按类型分:
- number:所有数字包括十六进制和科学计数法
- boolean:true 或 false
- string
- function:可以在代码中实现某种功能的语句块
- table:lua语言的核心之一,类似于哈希表
- userdata(自定义类型):脚本用户只能使用,而不能对其进行定义
- thread:线程可用于异步计算的协同程序
- nil(空类型):空
按作用域分:
- 全局变量:
- 局部变量:local修饰
举个栗子:在这个函数num()中。i就是一个局部变量,他被关键字local定义,只在函数num()中有效。而变量没有用local定义,j就是一个全局变量,在整个程序中都有效。不论在什么地方,只要没有被local定义的变量就是全局变量。
function num()
local i = 1
j = 2
end
练习题:
来证明两个变量的作用域。写一个函数,要包含两个同名的变量,一个局部变量,一个全局变量。并输出在屏幕上,来证明两个变量的作用域。
答案:
function num()
local i = 1
j = 2
print(i)
print(j)
end
num()
print(i)
print(j)
输出结果:
1
2
nil
2
二、运算符
加法 | + |
减法 | - |
乘法 | * |
除法 | / |
幂 | ^ |
取模 | % |
取负 | - |
等于 | == |
小于 | < |
大于 | > |
小于等于 | <= |
大于等于 | >= |
不等于 | ~= |
和 | and |
或 | or |
非 | not |
链接 | ·· |
三、初识函数
1、在lua中,函数都是function类型的对象,他可以被比较,可以赋值给一个变量,传递给函数,从函数中返回,或者作为table表中的键(表我们以后会讲到)。
2、定义一个函数它可以接收任意多个参数供其使用。另外,一个函数可以在它结束的时候返回任意多个值。return关键字的作用就是在函数中返回某些值。
ps:关于函数,在其他流行编程语言中,函数只是类的一部分,它不是对象。所以,你不能将一个函数赋值给一个变量或者进行相等不相等的比较,你更不可以在一个函数中去定义另一个函数。
定义方式:
第一种(重要):
function 函数名(参数)
函数内容
return 返回值 --可以没有
end
第二种:
函数名 = function(参数)
函数内容
return 返回值 --可以没有
end
举个栗子
function compute(a,b)
local x = a+b
local y = a-b
return x,y
end
i,j = compute(5,2)
print(i.." : "..j)
函数库:
math库、string库、io库、table库等。。
可变参数: …
function f(...) --三个点表示函数的参数个数不确定
function f(a,b,...) --函数有两个固定的参数,其他参数不确定
f(3) --a=3,b=nil,arg={n=0}
f(3,4) --a=3,b=4,arg={n=0}
f(3,4,5,8) --a=3,b=4,arg={5,8;n=2}
四、判断语句
格式:
第一种
if 表达式 then
语句块
end
第二种
if 表达式 then
语句块1
else
语句块2
end
第三种
if 表达式1 then
语句块1
elseif 表达式2 then
语句块2
else
语句块3
end
举个栗子
function f(i)
if i>90 and i<=100 then
print("优秀")
elseif i>70 and i<=90 then
print("良好")
elseif i>60 and i<=70 then
print("及格")
else
print("不及格")
end
end
f(65)
五、循环语句
格式:
第一种
while 循环条件 do
循环体
end
第二种
repeat
循环体
until 循环条件
第三种
for 变量=初始值,终止值,步长 do
循环体
end
ps: 初始值、终止值还有步长三个部分都只会被执行一次。所以,即使你使用变量或表达式代替终止值和步长,在循环体中又不小心改变了终止值和步长,循环也能正常结束。
循环体内可以被break或return打断
举个栗子
打印100以内7的倍数
function f()
local i = 0
while i<=100 do
if i%7==0 then
print(i)
end
i=i+1
end
end
f()
function f()
local i = 0
repeat
if i%7==0 then
print(i)
end
i=i+1
until i>100
end
f()
function f()
for i=0,100,1 do
if i%7==0 then
print(i)
end
end
end
f()
打印前20个斐波那契数列
循环方法
function f()
local a=1
local b=1
local t=0
print(a)
print(b)
for i=0,17,1 do
t=a
a=a+b
b=t
print(a)
end
end
f()
结果
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
递归方法
function f(a)
if a<=2 and a>0 then
return 1
else
return f(a-1)+f(a-2)
end
end
for i=20,1,-1 do
print(f(i))
end
结果
6765
4181
2584
1597
987
610
377
233
144
89
55
34
21
13
8
5
3
2
1
1
六、表
类似于java里面的数组
举个栗子
array = {} --空表
array = {"a","b","c"} --默认key的表。array[1]索引到"a"。注意key是从1开始的
array = {"vv",name="bb","cc"} --自定义key的表。array["name"]索引到"bb",注意name要加引号。 没有自定义key的按默认的key增加,分配时跳过自定义key
-----------------------分割线---------------------------
元素赋值
array = {}
array["name"] = "a"
array["phone"] = "123"
array.city = "beijing"
array.sex = "boy"
print(array["sex"])
元素删除
array.sex = nil
array["name"] = nil
练习题
如何将函数作为表二点元素添加进去?
array = {}
array.func = function()
print("这是一个函数")
end
array.func()
定义一个空表,然后将函数直接传递给表中的array.func,调用的时候需要加括号,因为它是一个函数。
1、表作为数组的应用:表中元素为同一数据类型
使用#可以获取数组的长度。
arr={"1","2"}
print(#arr)
for i=1,#arr,1 do
print(arr[i])
end
结果:
2
1
2
向数组中添加元素。使用 table.insert(数组,键,值)
从数组中删除元素。使用 table.remove(数组,键)
举个例子
table.insert(arr,2,"aa")
向arr数组中添加了键位2的值"aa"。原来键为2的值依次向后重新排列。
如果省略键,只填入数组名和值,那么就会默认把新添加的值放在数组最后一位。
练习题
将数组中的元素按从大到小排序
--冒泡排序
arr = {3,5,1,7,10,2}
for j = 1,#arr-1,1 do
for i=2,#arr-j+1,1 do
if arr[i]>arr[i-1] then
arr[i-1],arr[i] = arr[i],arr[i-1]
end
end
end
for i=1,#arr,1 do
print(arr[i])
end
2、库函数table.sort(数组,排序规则)
七、高级函数与控制结构
String.sun(字符串,开始下标,终止下标)
–截取字符串String.tonumber(字符串,进制)
–字符串转数字类型
返回值丢失
如果函数调用所得的多个返回值是另外一个函数的最后一个参数,或者是多指派表达式中的最后一个参数时,所有的返回值将被传入或使用,否则,只有第一个返回值被使用或指定。例如:
其中toRGB()
有三个返回值select()
函数它的作用是允许你指定从第几个返回值开始取值。这个函数可以接受任意数目的参数,其中第一个参数用来决定函数的行为,当第一一个参 数为“#”时,select(简单返回其余参数的个数,当第一个 参数为一个数字时,select()返 回其余从这个位置开始直到最后一个的参数:
函数的尾调用(重点)
当函数的最后返回结果是调用一个函数,称之为尾调函数。Lua在调用尾调函数时,先弹出当前函数的栈,然后再调用尾调函数,从而降低了函数层层调动过程中的栈消耗,非常适用于函数递归调用。
迭代器(pairs(集合)函数)与泛型for
for 变量列表 in 迭代器 do
语句块
end
举个栗子
tab = {"a","b","c"}
for i,j in pairs(tab) do
print(i..","..j)
end
结果
1,a
2,b
3,c
八、函数库
1.基本库
print()
打印tostring(123)
返回字符串“123”tonumber(参数)
将参数转化为数字type()
返回参数的类型名rawset(表,键,值)
更改表中指定键对应的值,返回表的指针rawget(表,键)
获取表中指定键对应的值,当键不存在时返回nilrawequal(num1,num2)
比较两个参数是否相等,返回boolean值(相等为true)dofile(程序块)
打开并执行一个lua程序块next(表,键)
允许程序遍历表中每个字段,返回下一个键和对应的值。此函数只能用于数字做键的表。pairs和ipairs
迭代器。pairs可以遍历表中所有的键,并且除了迭代器本身以及遍历表本身还可返回nil;但是ipairs则不能返回nil,只能返回0,如果遇到nil则退出。它只能遍历到表中出现的第一个不是整数的键。require(文件名)
搜索目录加载文件,并判断是否文件已经加载。使用本函数前一般需要用package.path(路径)
来指定搜索路径。
2.数学库,表库
table.concat(表,分隔符,开始下标,结束下标)
返回参数中表内从开始下标到结束下标中的所有数组部分,并用分隔符隔开。后三个参数为可选参数。
table.insert(表,键,值)
在指定表中插入一个指定的键和值。参数键可以省略。省略插入的值将被放置于表的最后一位。
table.maxn(表)
返回指定表中所有正数键值中最大的键。如果不存在键为正数的元素,则返回0.
table.remove(表,键)
删除并返回表的数组部分指定键的元素。其后的元素会被前移。如果省略键参,则从最后一个元素删起。
table.sort(表,comp)
对指定的表进行升序排序。comp可选参数,此参数是一个外部函数,可以自定义sort函数的排序标准,此函数应满足以下条件:接受两个参数a,b,并返回一个布尔型的值,当a应该排在b前面时,反悔true,否则返回false。
table.foreachi(表,function(i,v))
会期望一个从1开始的连续整数范围,遍历表中的键和值逐对进行function(i,v)操作。
table.foreach(表,function(i,v))
会对整个表进行遍历。
table.getn(表)
返回表中元素的个数
table.setn(表,个数)
设置表中元素的个数
3.字符串库
string.len(字符串)
字符串的长度string.rep(字符串,数值)
返回字符串的n个拷贝string.lower(字符串)
字符转小写string.lower(字符串)
字符转小写string.sub(字符串,参数,参数)
截取部分字符串string.byte(字符串,参数)
返回字符串中参数所指向字符的ascii码string.char(参数,参数,参数,...)
将ascii码转化为对应的字符string.gsub(字符串,被替换的字符串,替换的字符串,参数)
替换字符串的一部分,参数为需要替换的个数string.find(字符串,参数,开始位置)
查找在字符串中的某一部分,返回索引。string.format(格式化字符串,格式化参量)
4.操作系统库
os.clock()
返回一个程序使用cpu时间的一个近似值os.time(...)
按参数的内容返回一个时间值(数字),若不带参数则返回当前时间。os.tmpname()
返回一个临时文件名os.getenv(varname)
返回当前进程的环境变量varname的值,若变量没有定义则返回nilos.remove(filename)
删除文件os.rename(oldname,newname)
更改文件或目录名os.exit(code)
相当于C的exit函数,终止主程序os.difftime(t2,t1)
返回t1到t2相差的秒数os.date(format,time)
返回一个格式化日期、时间的字符串或表
5、流和文件库
简单IO:所有操作都是在两个当前文件之上
完全IO:为了更好的控制输入输出流,而添加了对输入输出文件句柄操作的一种模式。io.read(参数)
参数:
*all 读取整个文件
*line 读取下一行
*number 从串中转换出一个数值
num 读取num个字符串io.write()
与print的用法类似。可以用format函数进行格式化输出
io.input("账号.txt")
io.read() --读取账号.txt的内容
io.output("登录.txt")
io.write() --输出读取的内容到登录.txt
io.flush()
输出所有缓冲区的内容到输出文件io.close()
关闭打开的文件io.open(filename,mode)
按指定模式打开一个文件,成功则返回文件句柄,失败则返回nil+错误信息
mode:
r 读
w 写
a 添加
r+ 更新,之前数据被保存
w+ 更新,之前数据被删除
a+ 添加更新,之前数据被保存,只允许在文件尾进行添加