Lua入门
2014-02-18 20:29 fonzieyang 阅读(472) 评论(0) 收藏 举报Lua 入门
简单介
已经搬家到新博客 jjyy.guru
分享跟游戏相关的技术、编程心得、unity3d、cocos2d、emacs、操作系统
绍一下Lua,建议最好通读过manual知道基本语法再阅读此文,再深入的话,建议每一步都主动思考动手练习这里的内容之后,才开始学习其他高级内容,比如协程、绑定、用户数据、内省、gc、闭包、upvalue等等。
- 应该常阅读文档,至少通读一遍。
- http://www.lua.org/manual/5.1/manual.html
Lua工作机制
C通过栈和少量命令与Lua通信,通信流程如下:
- 放入约定的数据到Lua栈
- 执行命令,Lua即会将数据取走,返回的数据再次放入栈顶
- 栈平衡需要自己维护
来看看具体操作,C API 示例:
/* 1.执行Lua脚本,返回0代表成功 */int err = luaL_dofile(pL, "helloLua.lua");CCLOG("open : %d", err);/* 2.重置栈顶索引 */lua_settop(pL, 0);lua_getglobal(pL, "myName"); // 在global table中寻找myName/* 3.判断栈顶的值的类型是否为String, 返回非0值代表成功 */int isstr = lua_isstring(pL, 1);CCLOG("isstr = %d", isstr);/* 4.获取栈顶的值 */const char* str = lua_tostring(pL, 1);CCLOG("getStr = %s", str);
我们在使用lua c api的过程中,指定Lua栈上面的元素的序号是按照下面的方式排布的:
栈顶永远-1,栈底永远为1,简单记忆为“一直向上”(一值向上)
栈顶-1 5-2 4-3 3-4 2-5 1栈底
在Lua的世界里,一切魔法都是table造成的,通过基本元素组织起来,使得Lua非常优雅,基本的常见的元素如下,并且写了一些与c的不同:
- nil
赋值nil就是删除 - boolean
出了false和nil之外都认为真,所以Lua认为0和空字符串都为真 - number
Lua中数组下标从1开始 - string
- function
- userdata
对C数据的包装 - thread
- table
一些需要注意的基本语法:
- 没有continue没有switch-case
- Table["element"] 与 Table.element 等价,方便元编程
- Table构造语法{aa=1,bb=2},传参数常用
- G为全局表,所有全局变量存放的地方,因此G["element"] 与 element 等价
关于Lua Table
Table除了简单的操作之外,还可以通过metatable提供更加方便的控制,为table增加metatable很简单
tab = {}mt = {}setmetatable(tab,mt)
metatable通过在约定的值去控制table,主要控制是
- 访问
- 赋值
- operator
-
调用
这里只简单讲一下访问控制,当metatable中__index指向的table中存在要访问的元素,会优先访问该table,这就跟重载如出一辙,当然,你写入之后就会访问自己的数据,但在此之前,总会访问metatable的__index指向。注意__index除了可以指向table之外,还可以指向function,指向function会有更好的控制力度。其他类型的控制也雷同。
关于面向对象
在Lua中没有直接提供面向对象,但是由于metatable的强大功能,所以可以轻松构造面向对象特性,Lua创建与传统面向对象不同的地方就是没有通过类去创建实例。在Lua中一切都是Table,包括我们认知中的类。其实类只是辅助我们思考的东西,在内存中并不直接存在,所以需要我们直接从Table构造出我们所需要的特性。这里可以看到作者的用心,更少的机制,更多的工作,简洁到极致。
- 创造我们的Class
类实际上是用来创建实例的,所以我们构造的Class,就是一种可以创建实例的方法
struct Foo{int a;int b;void FooFunc(){}};function Foo()local t = {}t.a = 0t.b = 0t.FooFunc = function() endreturn tend
- 一个更好的版本
通过new出来实例,而不是通过调用函数得到,更符合我们的习惯
function Class()local t = {}t.__index = tt.New = function()local instance = {}setmetatable(instance, t)return instanceendreturn tendFoo = Class()Foo.a = 0Foo.b = 0Foo.FooFunc = function() end
- 实现继承
继承的特点一个个进行分析
* 拥有父类的数据 * 拥有父类的过程
struct Bar : public Foo{int c;};function class(type)local t = {}t.__index = tsetmetatable(t, type)t.New = function()local instance = {}setmetatable(instance, t)return instanceendreturn tendBar = class(Foo)Bar.c = 0
文件组织
为了全局名字污染最小化,尽可能地使用局部变量,包括类名,因此有如下文件组织模版
local Test2 = Class(Test1)Test2.func = function(aa,bb)endTest2.abc = "abc"return Test2
在另外一份lua文件中,可以这么使用
local Test2 = require "Test2"local Test3 = Class(Test2)...return Test3
浙公网安备 33010602011771号