Lua学习笔记(更新中)

Lua学习笔记(更新中)

部分细节

逻辑操作符

and、or使用短路求值:

  1. and 第一操作数为假,返回第一操作数
  2. or 第一操作数为真,返回第一操作数

字符串连接

“..”连接两个字符串,若其中任意一个操作数为数字的话默认转为字符串。

赋值语句

Lua允许多重赋值,可以通过多重赋值实现swap两个变量的功能。

局部变量和块

local语句创建局部变量,作用域为当前块。

尽可能地使用局部变量,避免将无用的名称引入全局变量。

使用do-end关键字显式定义一个块。

for循环体

数字型for

for var=exp1,exp2,exp3 do
    <执行体>
end

var从exp1变化到exp2,每次变化以exp3为指定步长递增var。
exp3可选,默认为1.

泛型for

泛型for循环通过一个迭代器(iterator)函数来遍历所有值。
ipairs函数迭代数组,pairs函数迭代table元素,io.lines函数迭代文件中的每行,string.gmatch函数迭代字符串中的单词。
泛型for在循环过程内部保存了迭代期函数,实际上保存三个值:一个迭代器函数、一个恒定状态和一个控制变量
变量列表的第一个元素称为“控制变量”,在循环过程中绝不会为nil,因为当它为nil时循环结束。
for做的第一件事情是对in后面的表达式求值,返回三个值,类似多重赋值,即只有最后一个表达式会产生多个结果,并且只会保留前三个值,多余的值会被丢弃,不足的会用nil补足。

注意

循环变量是局部变量;不应该对循环变量赋值;

函数多重返回值

Lua允许函数返回多个结果。
若一个函数调用是最后的一个表达式,保留尽可能多的返回值。
若函数没有返回值或者没有返回足够多的返回值,使用nil补充缺失的返回值。
若函数调用不是一系列表达式的最后一个元素,只产生一个返回值。
若函数调用作为另一个函数调用的最后一个实参是,第一个函数的所有返回值都将作为实参传入第二个函数。
return一个函数调用将返回该函数的所有返回值。
将函数调用放入一对圆括号中,迫使其只返回一个结果。

upack函数

变长参数

参数表中的3个点表示该函数可接受不同数量的实参。
表达式“…”类似于一个具有多重返回值的函数,返回的是当前函数的所有变长参数。

非全局函数

递归调用非全局函数时先定义一个局部变量再定义函数本身。
或者直接利用“local function foo()”形式定义,但这种方式对间接递归无效,必须使用明确的前向声明。

无状态迭代器

自身不保存任何状态的迭代器,避免产生closure开销。
ipairs和pairs均为无状态迭代器。

具有复杂状态迭代器

将迭代器所有状态打包为一个table,保存在恒定状态中。
通常基于closure实现的迭代期会比一个使用table的迭代器更为高效,因为创建一个closure比创建一个table更廉价,其次访问“非局部变量”比访问table字段更快。

编译

dofile函数从lua文件运行lua代码块。
loadfile不运行lua文件代码,只编译lua代码。
loadstring从一个字符串中读取代码,而非从文件读取。如果想实现dostring只需要直接调用loadstring返回值即可:

loadstring(s)()

如果代码中有语法错误,loadstring会返回nil,错误消息会变成试图调用一个nil值,为定位错误,使用assert。
将loadstring用于字面字符串是没有意义的,因为代码在每次调用loadstring时会重新编译,效率低。

错误处理和异常

使用error函数来抛出异常,使用pcall函数来捕获异常,错误消息可以表示出错误的类型或内容。

错误消息与追溯

协程

lua将关于协程的函数放置在名为coroutine的table中。函数create用于创建新的协程,参数为函数,创建后状态为挂起。
使用resume函数启动或者再次启动一个协程,将其状态从挂起转为运行。
使用yield函数让一个运行中的协程挂起,之后可以再次恢复其运行。
当协程执行完毕并已经返回,协程处于死亡状态,如果通过resume恢复它的运行会返回false和错误信息。
当一个协程A唤醒另一个协程B时,协程A处于特殊状态——“正常”状态。

猜你喜欢

转载自blog.csdn.net/zuimrs/article/details/80371435