【Lua】学习笔记-lua脚本
一、数据类型
只有一种数据类型:number 双精度浮点数
string可以用单引号双引号或者[[]]表示;
字符串连接使用的是 ..
使用 # 来计算字符串的长度
Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字或者是字符串。
table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。也可以在表里添加一些数据,直接初始化表
-- table_test.lua 脚本文件
a = {}
a["key"] = "value"
key = 10
a[key] = 22
a[key] = a[key] + 11for k, v in pairs(a) do
print(k .. " : " .. v)end
不同于其他语言的数组把 0 作为数组的初始索引,在 Lua 里表的默认初始索引一般以 1 开始。
table 不会固定长度大小,有新数据添加时 table 长度会自动增长,没初始的 table 都是 nil。
二、函数
在 Lua 中,函数是被看作是"第一类值(First-Class Value)",函数可以存在变量里:
function factorial1(n)
if n == 0 then
return 1
else
return n * factorial1(n - 1)
end
userdata 是一种用户自定义数据,用于表示一种由应用程序或 C/C++ 语言库所创建的类型,可以将任意 C/C++ 的任意数据类型的数据(通常是 struct 和 指针)存储到 Lua 变量中调用。
三、变量
变量在使用前,必须在代码中进行声明,即创建该变量。
编译程序执行代码之前编译器需要知道如何给语句变量开辟存储区,用于存储变量的值。
Lua 变量有三种类型:全局变量、局部变量、表中的域。
a = 5 -- 全局变量
local b = 5 -- 局部变量
应该尽可能的使用局部变量,有两个好处:
1. 避免命名冲突。
2. 访问局部变量的速度比全局变量更快。
Lua可以对多个变量同时赋值,可应用于函数多返回值的接收。
对 table 的索引使用方括号 [] Lua 也提供了 . 操作
t[i]
t.i -- 当索引为字符串类型时的一种简化写法
四、循环
1、while循环
while(condition)do
statements
end
2、for循环
1)数值for循环
for var=exp1,exp2,exp3 do
<执行体>
end
var从exp1变化到exp2,每次变化以exp3为步长递增var,并执行一次"执行体"。exp3是可选的,如果不指定,默认为1。
2)泛型for循环
类似java中的foreach语句
--打印数组a的所有值
for i,v in ipairs(a)
do print(v)
end
循环的索引 i 为外部索引,修改循环语句中的内部索引 i,不会影响循环次数
ipairs 这个迭代器只能遍历所有数组下标的值,这是前提,也是和 pairs 的最根本区别,也就是说如果 ipairs 在迭代过程中是会直接跳过所有手动设定值的变量。
pairs可以遍历表中所有的key,并且除了迭代器本身以及遍历表本身还可以返回nil;
五、条件语句
if(布尔表达式)then
--[ 布尔表达式为 true 时执行该语句块 --]
else
--[ 布尔表达式为 false 时执行该语句块 --]
end
函数
Lua 编程语言函数定义格式如下:
optional_function_scope function function_name( argument1, argument2, argument3..., argumentn)
function_body
return result_params_comma_separated
end
解析:
optional_function_scope: 该参数是可选的制定函数是全局函数还是局部函数,未设置该参数默认为全局函数,如果你需要设置函数为局部函数需要使用关键字 local。
function_name: 指定函数名称。
argument1, argument2, argument3..., argumentn: 函数参数,多个参数以逗号隔开,函数也可以不带参数。
function_body: 函数体,函数中需要执行的代码语句块。
result_params_comma_separated: 函数返回值,Lua语言函数可以返回多个值,每个值以逗号隔开。
可返回多值。
Lua函数可以接受可变数目的参数,和C语言类似在函数参数列表中使用三点(...) 表示函数有可变的参数。
例如,我们计算几个数的平均值:
function average(...)
result = 0
local arg={...}
for i,v in ipairs(arg) do
result = result + v
end
print("总共传入 " .. select("#",...) .. " 个数")
return result/select("#",...)
end
调用:print("平均值为",average(10,5,3,4,5,6))
六、运算符
与常用语言不太一样的运算符
符号 | 描述 |
^ | 乘幂 |
~= | 不等于,检测两个值是否相等,相等返回 false,否则返回 true |
# |
一元运算符,返回字符串或表的长度。eg:#"Hello" 返回 5 |
七、字符串
Lua 语言中字符串可以使用以下三种方式来表示:
单引号间的一串字符。
双引号间的一串字符。
[[和]]间的一串字符。
Lua 提供了很多的方法来支持字符串的操作:
序号 |
方法 & 用途 |
1 |
string.upper(argument): 字符串全部转为大写字母。 |
2 |
string.lower(argument): 字符串全部转为小写字母。 |
3 |
string.gsub(mainString,findString,replaceString,num) 在字符串中替换,mainString为要替换的字符串, findString 为被替换的字符,replaceString 要替换的字符,num 替换次数(可以忽略,则全部替换),如: > string.gsub("aaaa","a","z",3); zzza 3 |
4 |
string.find (str, substr, [init, [end]]) 在一个指定的目标字符串中搜索指定的内容(第三个参数为索引),返回其具体位置。不存在则返回 nil。 > string.find("Hello Lua user", "Lua", 1) 7 9 |
5 |
string.reverse(arg) 字符串反转 > string.reverse("Lua") auL |
6 |
string.format(...) 返回一个类似printf的格式化字符串 > string.format("the value is:%d",4) the value is:4 |
7 |
string.char(arg) 和 string.byte(arg[,int]) char 将整型数字转成字符并连接, byte 转换字符为整数值(可以指定某个字符,默认第一个字符)。 > string.char(97,98,99,100) abcd > string.byte("ABCD",4)68> string.byte("ABCD")65> |
8 |
string.len(arg) 计算字符串长度。 string.len("abc")3 |
9 |
string.rep(string, n) 返回字符串string的n个拷贝 > string.rep("abcd",2) abcdabcd |
10 |
.. 链接两个字符串 > print("www.runoob".."com") www.runoobcom |
11 |
string.gmatch(str, pattern) 回一个迭代器函数,每一次调用这个函数,返回一个在字符串 str 找到的下一个符合 pattern 描述的子串。如果参数 pattern 描述的字符串没有找到,迭代函数返回nil。 > for word in string.gmatch("Hello Lua user", "%a+") do print(word) endHelloLua user |
八、table
以下列出了 Table 操作常用的方法:
序号 |
方法 & 用途 |
1 |
table.concat (table [, sep [, start [, end]]]): concat是concatenate(连锁, 连接)的缩写. table.concat()函数列出参数中指定table的数组部分从start位置到end位置的所有元素, 元素间以指定的分隔符(sep)隔开。 |
2 |
table.insert (table, [pos,] value): 在table的数组部分指定位置(pos)插入值为value的一个元素. pos参数可选, 默认为数组部分末尾. |
3 |
table.maxn (table) 指定table中所有正数key值中最大的key值. 如果不存在key值为正数的元素, 则返回0。(Lua5.2之后该方法已经不存在了,本文使用了自定义函数实现) |
4 |
table.remove (table [, pos]) 返回table数组部分位于pos位置的元素. 其后的元素会被前移. pos参数可选, 默认为table长度, 即从最后一个元素删起。 |
5 |
table.sort (table [, comp]) 对给定的table进行升序排序。 |
九、Lua模块
Lua 的模块是由变量、函数等已知元素组成的 table,因此创建一个模块很简单,就是创建一个 table,然后把需要导出的常量、函数放入其中,最后返回这个 table 就行。以下为创建自定义模块 module.lua,文件代码格式如下:
-- 文件名为: module.lua
-- 定义一个名为 module 的模块:module = {}
-- 定义一个常量:module.constant = "这是一个常量"
-- 定义一个函数:
function module.func1()
io.write("这是一个公有函数!\n")
end
local function func2()
print("这是一个私有函数!")
end
function module.func3()
func2()
end
return module
由上可知,模块的结构就是一个 table 的结构,因此可以像操作调用 table 里的元素那样来操作调用模块里的常量或函数。
require的函数用来加载模块
require("<模块名>") 或 require "<模块名>"
十、协程
方法 |
描述 |
coroutine.create() |
创建coroutine,返回coroutine, 参数是一个函数,当和resume配合使用的时候就唤醒函数调用 |
coroutine.resume() |
重启coroutine,和create配合使用 |
coroutine.yield() |
挂起coroutine,将coroutine设置为挂起状态,这个和resume配合使用能有很多有用的效果 |
coroutine.status() |
查看coroutine的状态 注:coroutine的状态有三种:dead,suspend,running,具体什么时候有这样的状态请参考下面的程序 |
coroutine.wrap() |
创建coroutine,返回一个函数,一旦你调用这个函数,就进入coroutine,和create功能重复 |
coroutine.running() |
返回正在跑的coroutine,一个coroutine就是一个线程,当使用running的时候,就是返回一个corouting的线程号 |
Lua 采用了自动内存管理