Lua笔记(一)

创建日期2020-04-03 19:44
最后修改2020-04-04 03:44

关于《Programming In Lua》这本书的笔记

  • 1 Chunk:交互模式每行都是独立的Chunk,文件里每个文件是一个Chunk
  • 2 默认全局、除非用local修饰
  • 3 基本类型:nilbooleannumberstringuserdatafunctionthreadtable
  • 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 通用forfor <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 弱keygetmetatable(t).__mode == "k"。该模式下table对它的key持弱引用,所以当外部没有对这个key的强引用时,这个key会被回收,同时table里会同时移除这一条目。
  • 19 弱valuegetmetatable(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时会同时调用这个析构函数释放相关的资源
CopyRight(C) Zheqi Yu 2016-2024