lua学习笔记(持续更新中)

时间:2022-12-03 22:15:47

lua 笔记:

*当且仅当一个变量不等于nil时,这个变量存在

*注释:单行注释:--  多行注释:--[[    --]]

*在控制结构的条件中除了false和nil为假,其他值都为真。所以Lua认为0和空串都是真

*Numberss表示实数,Lua中没有整数
*Lua比较数字按传统的数字大小进行,比较字符串按字母的顺序进行,但是字母顺序依赖于本地环境
*逻辑运算符认为false和nil是假(false)  特别注意 nil

*a and b -- 如果a为false,则返回a,否则返回b
 a or b -- 如果a为true,则返回a,否则返回b

*当一个字符串使用算术操作符时,string就会被转成数字

*~= 不等于的意思

*..在Lua中是字符串连接符,当在一个数字后面写..时,必须加上空格以防止被解释错
*注意:如果要对多个变量赋值必须依次对每个变量赋值

三个表达式只会被计算一次,并且是在循环开始前。
for i=1,f(x) do
print(i)
end

*函数可以存储在变量中,可以作为函数的参数,也可以作为函数的返回值。

*userdata可以将C数据存放在Lua变量

 

*Lua有着如下的特性:1、变量名没有类型,值才有类型,变量名在运行时可与任何类型的值绑定;2、语言只提供唯一一种数据结构,称为表(table),它类似key
-value关联数组,可以用任何类型的值作为key和value。提供了一致且富有表达力的表构造语法,使得Lua很适合描述复杂的数据;3、函数是一
等类型,支持匿名函数和正则尾递归(proper tail recursion);4、支持词法定界(lexical
scoping)和闭包(closure);5、提供thread类型和结构化的协程(coroutine)机制,在此基础上可方便实现协作式多任务;
6、运行期能编译字符串形式的程序文本并载入虚拟机执行;7、通过元表(metatable)和元方法(metamethod)提供动态元机制
(dynamic
meta-mechanism),从而允许程序运行时根据需要改变或扩充语法设施的内定语义;8、能方便地利用表和动态元机制实现基于原型
(prototype-based)的面向对象模型;9、从5.1版开始提供了完善的模块机制,从而更好地支持开发大型的应用程序;

*闭包的两个特点:
1、作为一个函数变量的一个引用 - 当函数返回时,其处于激活状态。
2、一个闭包就是当一个函数返回时,一个没有释放资源的栈区。


*C调用lua脚本
void load (char *filename, int *width, int *height) {
lua_State *L = lua_open();
luaopen_base(L);
luaopen_io(L);
luaopen_string(L);
luaopen_math(L);
if (luaL_loadfile(L, filename) || lua_pcall(L, 0, 0, 0))
error(L, "cannot run configuration file: %s",
lua_tostring(L, -1));
lua_getglobal(L, "width");
lua_getglobal(L, "height");
if (!lua_isnumber(L, -2))
error(L, "`width' should be a number/n");
if (!lua_isnumber(L, -1))
Programming in Lua 189
Copyright ? 2005, Translation Team, www.luachina.net
error(L, "`height' should be a number/n");
*width = (int)lua_tonumber(L, -2);
*height = (int)lua_tonumber(L, -1);
lua_close(L);
}

*lua 调用 C函数
 当Lua调用C函数的时候,第一个参数总是在这个私有栈的index=1的位置。甚至当一个C函数调用Lua代码(Lua代码调用同一个C函数或者其他的C函数),每一个C函数都有自己的独立的私有栈,并且第一个参数在index=1的位置

*协同有三个状态:挂起态、运行态、停止态。当我们创建一个协同程序时他开始的状态为挂起态

*包库为Lua提供简易的加载及创建模块的方法,由require、module方法及package表组成
1、module (name [, ···])
功能:建立一个模块。
     当package.loaded[name]中存在时,当中的表作为module;
     当在全局表中存在name指定的表时,此表作为module;
     当以前两种情况都不存表name时,将新建一个表,并使其作为全局名name的值,并package.loaded[name],而且设t._NAME为name,t._M为module,t._PACKAGE为包的全名(模块名-组件a.b.c);最后把此module设t作为当前函数的新环境表和package.loaded[name]的新值(也就是说,旧的环境表将不能访问,除了加上package.seeall参数外),以被require使用

module(name)后的可选参数为接收module名的函数,如package.seeall

*require (modname)
功能:加载指定的模块。
   此函数先检测package.loaded表中是否存在modname,存在则直接返回当中的值,没有则通过郰定义的加载器加载modname。
查找加载器顺序:
    (1)检测package.preload表是否存在modname,有则加载
    (2)通过Lua Loader加载,通过查找存放于package.path的路径加载,有则加载
    (3)通过C Loader加载,通过查找存放于package.cpath的路径加载,有则加载
    (4)通过all-in-one Loader加载:
      通过查找modname.dll并查找当中的luaopen_<XXXX>
      其中XXXX为载块名-后的字符用_替换.后的字符:如:a.v1-b.c 当函数名为luaopen_b_c
    当require查找的不是一个Lua库或C库,它就会调用all-in-one loader,此加载器是用C路径作为载块的目录,
    当查找到合适的加载器时,require就会加载其中的模块,当加载器有返回值,将会存放于package.loaded[modname]表。最后返回package.loaded[modname]表
    当加载失败时,require将触发错误

*Metatable中定义的操作add, sub, mul, div, mod, pow, unm, concat, len, eq, lt, le, tostring, gc, index, newindex, call...
Lua本身提供的功能中, 不允许你改变除了table类型值外的任何其他类型值的Metatable, 除非使用C扩展或其他库. setmetatable和getmetatable
是唯一一组操作table类型的Metatable的方法.

Metatable与面向对象
 Lua是个面向过程的语言, 但通过Metatable可以模拟出面向对象的样子. 其关键就在于__index这个域. 他提供了表的索引值入口. 这很像重写C#中的索引器, 当表要索引一个值时如table[key], Lua会首先在table本身中查找key的值, 如果没有并且这个table存在一个带有__index属性的Metatable, 则Lua会按照__index所定义的函数逻辑查找. 仔细想想, 这不正为面向对象中的核心思想继承, 提供了实现方式么. Lua中实现面向对象的方式非常多, 但无论哪种都离不开__index.


*userdata 类型用来将任意 C 数据保存在 Lua 变量中

*以身试法  luavs.bat  不适用于VS2008
阅读INSTALL发现如下:
If all you want is to build the Lua interpreter, you may put all .c files in a single project, except for luac.c and print.c.

那么,很简单,新建一个空工程,导入src下除luac.c和print.c的所有C文件(意思是里面的Makefile不用导入啦=.=)
然后直接编译所有文件就OK了