Lua笔记(一)
关于《Programming In Lua》这本书的笔记
- 1 Chunk:交互模式每行都是独立的Chunk,文件里每个文件是一个Chunk
- 2 默认全局、除非用
local
修饰 - 3 基本类型:
nil
、boolean
、number
、string
、userdata
、function
、thread
、table
- 4 加号
+
只做数学运算,字符串拼接使用..
- 5
table
的长度只计算数组部分,但是如果有洞不要乱用(TODO看C-API) - 6 取模运算符:
a % b == a - floor(a / b) * b
- 7 数值
for
,三个表达式只在进入循环前计算一次;循环变量是个local
变量;不要给循环变量赋值 - 8
...
,变长参数。unpack{...} == ...
- 9
select(id, ...)
,返回第id
及之后的参数(5.3);返回第id
个参数(5.1)。如果id == "#"
,返回参数数量 - 10
local
的作用范围。local
变量如果重新定义,会产生一个新的,前面引用的不变,后面引用新的 - 11 通用
for
:for <var-list> in <exp-list> do <body> end
,<exp-list>
返回迭代器函数、状态、控制变量三样东西。每次循环以状态与控制变量为参数调用迭代器函数,函数的第一个返回值赋值给控制变量作为下一轮的参数。控制变量为nil
时退出循环,否则执行for
的循环体
for var1, var2, ... in <exp-list> do
<body>
end
do
local _f, _s, _c = <exp-list>
while true do
local var1, var2, ... = _f(_s, _c)
_c = var1
if _c == nil then break end
<body>
end
end
- 12 数据描述
data{...}
。等价于data({...})
,Chunk会返回一个函数,这个函数存在一个upvalue为global的data
函数,外部定义data
,并调用这个Chunk,实现以不同方法处理同一段数据 - 13 metatable。
__index
和__newindex
分别控制读写table
属性不存在时的行为 - 14 全局环境。Lua中全局变量挂在
_G
表中。可以用metatable控制全局变量的访问行为 - 15 局部环境。5.3里没有函数
setfenv(level, env)
。对应的可以直接在函数里修改upvalue_ENV
。默认_ENV
和_G
指向同一个table
。 - 16
require(name)
。package.loaded
记录了所有已经加载的模块。require
的参数会传递给Chunk函数作为参数;Chunk函数如果返回nil
(没有显式返回也返回nil
),package.loaded[name]
的值就是true
,否则就是那个返回值;require(name)
的返回值就是加载后package.loaded[name]
的值 - 17 弱表。如果一个表的metatable里有
__mode
属性,那就可能是弱表。__mode
是一个string
,"k"
表示key是弱引用,"v"
表示value是弱引用。只被弱引用的对象也会被回收。 - 18 弱key
getmetatable(t).__mode == "k"
。该模式下table
对它的key持弱引用,所以当外部没有对这个key的强引用时,这个key会被回收,同时table
里会同时移除这一条目。 - 19 弱value
getmetatable(t).__mode == "v"
。该模式下table
的key对它的value持弱引用,所以当外部没有对这个value的强引用时,这个value会被回收(TODO验证key是否回收)。 - 20 Lua头文件自身没有
extern "C"
,所以在C++
中使用时要在引用时写上,或者直接用#include <lua.hpp>
- 21 Lua栈索引为正表示从底开始,最底部索引是1;为负表示从顶开始,栈顶索引是-1
- 22 Lua中给C函数绑Lua的值。全局:Lua提供了registry表,所有C函数共享,可以用API来访问。模块内:Lua5.1的C函数环境被删除,可以用
LuaL_setfuncs()
函数替代,来为一组函数共享相同的upvalue。函数内:Lua提供了lua_pushcclosure()
函数来单独为函数指定upvalue - 23 metatable控制
userdata
的类型。这样的metatable必须显示指定名字作为key,存放在registry表中,所以要避免重名 - 24 userdata如果比较复杂,可能需要相应的析构函数。在metatable里设置
__gc
为该析构函数,Lua在GC这个userdata时会同时调用这个析构函数释放相关的资源