Lua学习
因为Moongen的需要,学习了一些Lua知识,特此总结。
现在更新到lua的模块与包。
注释
字符串匹配模式以后补充。
包的加载机制和C包以后补充。
1 | brew install lua |
注:lua的index都是从1开始的。
Lua数据类型
- nil
- boolean
- number
- string
- function
- userdata
- thread
- table
nil
nil表示值无效,对于全局变量和table,nil还有删除的作用,赋值为nil之后即删除了这个值
注:不能说type(X) == nil
,而要说type(X) == "nil"
,因为type(type(X)) == string
boolean
分为true
和false
,而且nil
的值也为false
。
number
lua默认只有一种number类型:double。(默认类型可以在luacof.h中修改)
string
字符串类型。
[[]]
用来表示一整块字符。
..
用来连接字符串。
在对一个数字字符串上进行算术操作时,Lua会尝试将这个数字字符串转成一个数字。
使用#
来计算字符串,比如
1 | > print(#"www") |
table
table的创建通过构造表达式来完成。
1 |
|
table实际上是一个关联数组(就是一个map),初始化的表通过index可以访问,但是index从1开始。
遍历一张表
1 | for key, val in pairs(t) do |
赋值或访问
1 | print(tbl1[1]) |
function
lua中函数被看成第一类值。
函数可以被存在变量里,即
1 | function (n) |
这时输出的两个值完全一致。
function还可以通过匿名函数的方式传递
1 | function testFun(tab,fun) |
Lua变量
Lua有三种变量,全局变量、局部变量、表中的域
直接声明即为全局变量。
局部变量通过local
声明。局部变量的作用范围为包围他的语句块。
1 | a = 5 -- 全局变量 |
赋值语句
直接赋值=
可以对多个变量同时赋值,如a, b = c, d
。赋值的时候Lua会先计算右边所有的值,再赋值,这样可以直接用同时赋值的方法交换变量。
变量个数>值的个数的时候,按变量个数补nil。
变量个数<值的个数的时候,忽略多余变量。
多个值赋值常常用来交换变量,或者获得函数返回值,如a, b = f()
。
Lua循环
分为while、for、repeat三种。并支持break。
1 | while (condition) |
泛型for循环
通过一个迭代器函数来遍历所有值。
1 | --打印数组a的所有值 |
其中ipairs为Lua提供的一个迭代器函数,用来迭代数组。
Lua流程控制
即if语句和嵌套。
1 | if (布尔表达式) |
Lua函数
函数定义为
1 | optional_function_scope function function_name( argument1, argument2, argument3..., argumentn) |
- optional_function_scope: 该参数是可选的制定函数是全局函数还是局部函数,未设置该参数默认为全局函数,如果你需要设置函数为局部函数需要使用关键字 local。
- function_name: 指定函数名称。
- argument1, argument2, argument3…, argumentn: 函数参数,多个参数以逗号隔开,函数也可以不带参数。
- function_body: 函数体,函数中需要执行的代码语句块。
- result_params_comma_separated: 函数返回值,Lua语言函数可以返回多个值,每个值以逗号隔开。
多返回值
用逗号隔开
可变参数
在函数列表中使用...
表示可变参数。
调用的时候可以通过table方式调用。(相当于传入一个map)
1 | function average(...) |
也可以通过select("#",...)
来获得可变参数的数量。
如果需要固定参数,在...
前面加上好了,一样逗号隔开,但是必须放在可变参数之前。
可变参数单个访问可以用select(i, ...)
访问第i
个元素。
Lua运算符
算术运算符+
,-
,*
,/
,%
,^
,-
关系运算符==
,~=
(不等于),>
,<
,>=
,<=
逻辑运算符and
,or
,not
其他运算符..
(连接两个字符串),#
(返回字符或表的长度)
Lua字符串
字符串可以用如下三种方法表示
- 单引号间的一串字符。
- 双引号间的一串字符。
- [[和]]间的一串字符。
字符串操作
注:下面的string
为保留字
string.upper():转成大写字母
string.lower():转成小写字母
string.gsub(mainString, findString, replaceString[, num]):在字符串中将mainString中的findString全部用replaceString替换num次,无num则全部替换。
string.find(str, substr, [init[, end]]):从init到end在str中寻找substr
string.reverse(str):翻转
string.format(…):像printf一样
string.char(arg)和string.byte(arg[, int]):在char和int之间转换。byte函数的int用来指定第几个字符,默认第一个。char函数可以有多个参数,返回连在一起的字符串。
string.len(arg):字符串长度
string.rep(string, n):重复string n次。
..:连接字符串
string.gmatch(str, pattern):返回一个迭代器函数。每一次调用函数返回下一个符合pattern描述的子串
1
for word in string.gmatch("Hello Lua user", "%a+") do print(word) end
string.match(str, pattern[, init]):返回第一个匹配出的子串(?这个好像解释不对,没有试过)
string.format
- %c - 接受一个数字, 并将其转化为ASCII码表中对应的字符
- %d, %i - 接受一个数字并将其转化为有符号的整数格式
- %o - 接受一个数字并将其转化为八进制数格式
- %u - 接受一个数字并将其转化为无符号整数格式
- %x - 接受一个数字并将其转化为十六进制数格式, 使用小写字母
- %X - 接受一个数字并将其转化为十六进制数格式, 使用大写字母
- %e - 接受一个数字并将其转化为科学记数法格式, 使用小写字母e
- %E - 接受一个数字并将其转化为科学记数法格式, 使用大写字母E
- %f - 接受一个数字并将其转化为浮点数格式
- %g(%G) - 接受一个数字并将其转化为%e(%E, 对应%G)及%f中较短的一种格式
- %q - 接受一个字符串并将其转化为可安全被Lua编译器读入的格式
- %s - 接受一个字符串并按照给定的参数格式化该字符串
匹配模式
因为现在不用,暂时就不放了,相关连接
http://www.runoob.com/lua/lua-strings.html
Lua数组
一维数组很简单a = {}
多维数组也很简单
1 | array = {} |
Lua迭代器
ipairs和pairs的区别
pairs会返回所有key和value,而ipairs会从index为1开始,遇到value为nil就停止。
无状态的迭代器和多状态的迭代器
for泛型的调用过程
在这之前,有必要讲一下for泛型的调用过程。
对于一个for泛型所需要的迭代器内容,共有三个值:迭代函数、状态常量、控制变量。执行过程如下:
- 首先,初始化,计算in后面表达式的值,表达式应该返回泛型 for 需要的三个值:迭代函数、状态常量、控制变量;与多值赋值一样,如果表达式返回的结果个数不足三个会自动用nil补足,多出部分会被忽略。
- 第二,将状态常量和控制变量作为参数调用迭代函数(注意:对于for结构来说,状态常量没有用处,仅仅在初始化时获取他的值并传递给迭代函数)。
- 第三,将迭代函数返回的值赋给变量列表。
- 第四,如果返回的第一个值为nil循环结束,否则执行循环体。
- 第五,回到第二步再次调用迭代函数
无状态的迭代器
无状态的迭代器指不保留任何状态,每一次迭代,迭代函数都是用两个变量(状态常量和控制变量)的值作为参数被调用。典型例子是ipairs。以下是一个例子
1 | function square(iteratorMaxCount,currentNumber) |
多状态的迭代器
很多情况下,迭代器需要保存多个状态信息而不是简单的状态常量和控制变量,最简单的方法是使用闭包,还有一种方法是将所有的状态信息封装到table中,将table作为迭代器的状态常量。以下是一个遍历table的迭代器。
1 | array = {"Lua", "Tutorial"} |
Lua table
table操作
注:下面的table为保留字
- table.concat(table[, sep[, start[, end]]]):将table从start到end的所有东西用sep(分隔符)隔开并连接在一起
- table.insert(table[, pos], value):在table数组部分pos位置插入值为value的元素
- table.maxn(table):指定table中所有正数key值中最大的key,如果不存在key值为正数的返回0.(在Lua5.2之后不存在了)
- table.remove(table[, pos]):返回table数组位于pos的元素,后面的元素会前移。
- table.sort(table[, comp]):对给定的table进行升序排序。
Lua模块与包
模块类似与一个封装库,Lua的模块是由变量、函数等已知元素组成的table,因此创建一个模块就是创建一个table,将需要导出的常量和函数放入其中,最后返回这个table就行了。
模块示例
1 | -- 文件名为 module.lua |
require函数
使用require("模块名")
或者require"模块名"
来加载模块。如果直接使用require
的话,lua会定义与这个模块名相同的全局变量。如下:
1 | require("module") |
也可以给它赋值m = require("模块")
,此时m
就是一个别名变量。
加载机制
以后补充。
C包
以后补充。