首页 > 其他 > 详细

Lua入门

时间:2014-02-19 16:04:59      阅读:349      评论:0      收藏:0      [点我收藏+]

Lua 入门

简单介绍一下Lua,建议最好通读过manual知道基本语法再阅读此文,再深入的话,建议每一步都主动思考动手练习这里的内容之后,才开始学习其他高级内容,比如协程、绑定、用户数据、内省、gc、闭包、upvalue等等。

Lua工作机制

C通过栈和少量命令与Lua通信,通信流程如下:

  • 放入约定的数据到Lua栈
  • 执行命令,Lua即会将数据取走,返回的数据再次放入栈顶
  • 栈平衡需要自己维护

来看看具体操作,C API 示例:

  1. /* 1.执行Lua脚本,返回0代表成功 */
  2. int err = luaL_dofile(pL, "helloLua.lua");
  3. CCLOG("open : %d", err);
  4. /* 2.重置栈顶索引 */
  5. lua_settop(pL, 0);
  6. lua_getglobal(pL, "myName"); // 在global table中寻找myName
  7. /* 3.判断栈顶的值的类型是否为String, 返回非0值代表成功 */
  8. int isstr = lua_isstring(pL, 1);
  9. CCLOG("isstr = %d", isstr);
  10. /* 4.获取栈顶的值 */
  11. const char* str = lua_tostring(pL, 1);
  12. CCLOG("getStr = %s", str);

我们在使用lua c api的过程中,指定Lua栈上面的元素的序号是按照下面的方式排布的:

栈顶永远-1,栈底永远为1,简单记忆为“一直向上”(一值向上)

  1. 栈顶
  2. -1 5
  3. -2 4
  4. -3 3
  5. -4 2
  6. -5 1
  7. 栈底

在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很简单

  1. tab = {}
  2. mt = {}
  3. setmetatable(tab,mt)

metatable通过在约定的值去控制table,主要控制是

  • 访问
  • 赋值
  • operator
  • 调用

    这里只简单讲一下访问控制,当metatable中__index指向的table中存在要访问的元素,会优先访问该table,这就跟重载如出一辙,当然,你写入之后就会访问自己的数据,但在此之前,总会访问metatable的__index指向。注意__index除了可以指向table之外,还可以指向function,指向function会有更好的控制力度。其他类型的控制也雷同。

关于面向对象

在Lua中没有直接提供面向对象,但是由于metatable的强大功能,所以可以轻松构造面向对象特性,Lua创建与传统面向对象不同的地方就是没有通过类去创建实例。在Lua中一切都是Table,包括我们认知中的类。其实类只是辅助我们思考的东西,在内存中并不直接存在,所以需要我们直接从Table构造出我们所需要的特性。这里可以看到作者的用心,更少的机制,更多的工作,简洁到极致。

  • 创造我们的Class

类实际上是用来创建实例的,所以我们构造的Class,就是一种可以创建实例的方法

  1. struct Foo{
  2. int a;
  3. int b;
  4. void FooFunc(){}
  5. };
  6. function Foo()
  7. local t = {}
  8. t.a = 0
  9. t.b = 0
  10. t.FooFunc = function() end
  11. return t
  12. end
  • 一个更好的版本

通过new出来实例,而不是通过调用函数得到,更符合我们的习惯

  1. function Class()
  2. local t = {}
  3. t.__index = t
  4. t.New = function()
  5. local instance = {}
  6. setmetatable(instance, t)
  7. return instance
  8. end
  9. return t
  10. end
  11. Foo = Class()
  12. Foo.a = 0
  13. Foo.b = 0
  14. Foo.FooFunc = function() end
  • 实现继承

继承的特点一个个进行分析

* 拥有父类的数据* 拥有父类的过程

  1. struct Bar : public Foo{
  2. int c;
  3. };
  4. function class(type)
  5. local t = {}
  6. t.__index = t
  7. setmetatable(t, type)
  8. t.New = function()
  9. local instance = {}
  10. setmetatable(instance, t)
  11. return instance
  12. end
  13. return t
  14. end
  15. Bar = class(Foo)
  16. Bar.c = 0

文件组织

为了全局名字污染最小化,尽可能地使用局部变量,包括类名,因此有如下文件组织模版

  1. local Test2 = Class(Test1)
  2. Test2.func = function(aa,bb)
  3. end
  4. Test2.abc = "abc"
  5. return Test2

在另外一份lua文件中,可以这么使用

  1. local Test2 = require "Test2"
  2. local Test3 = Class(Test2)
  3. ...
  4. return Test3

Lua入门

原文:http://www.cnblogs.com/fonzieyang/p/3554843.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!