lua总结

lua环境

lua环境由所有可操作的数据构成。
如编译好的函数,变量以及其他运行时内存。
这些数据保存在一个称作lua_State的结构中。所有lua应用程序都要求至少有一个lua_State。
如果需要还可多个(如需要为两个不同的系统保存不同的数据时)。

Lua环境是用来发送和接受数据的地方,它利用栈来达到该目的。
Lua栈不同于系统栈,它只能通过Lua的API函数访问。

元表

Lua中得每个值都有一套预定义的操作集合。即一个元表。

table和userdata可以有各自独立的元表,而其他类型的值则共享其类型所属的单一元表。

lua在创建新的table时不会创建元表.

    t = {}
    print(getmetatable(t)) — > nil

    --可以使用setmetatable来设置或修改任何table的元表
    t1 = {}
    setmetatable(t,t1)

可以通过元表来修改一个值的行为,使其在面对一个非预定义的操作时执行一个指定的操作。
假设a和b都是table,通过元表可以定义如何计算a+b。当lua试图将2个table相加时,会先检查两者之一是否有元表,然后检查该元表中是否有一个_add的字段。如果lua找到了该字段,就调用该字段对应的值。

任何table都可以作为任何值的元表,而一组相关的table也可以共享一个通用的元表,这个元表描述了它们共同的行为。一个table甚至可以作为它自己的元表,用于描述其特有的行为。

lua中只能设置table的元表。若要设置其他类型的值的元表,则必须通过c代码来完成。

元方法

当访问一个table中不存在的字段时,会促使解释器去查找一个叫__index的元方法。由这个元方法提供最终结果。

    Window = {}
    Window.mt = {}

    --构造函数
    function Window.new(0)
     —元表
     setmetatable(o,window.mt)
     return o
    end

    Window.prototype = {x=0,y=0,width=100,height=100}

    Window.t.__index = function(table.key)
     return Window.prototype[key]
    end
    --等价于
    Window.t.__index = Window.prototype

    w = Window.new(x=10,y=20)
    print(w.width)  —>100

当lua检测到w中没有某字段,而其元表中却有一个__index字段,那么lua就会以w来调用这个__index元方法。随后元方法用这个key来索引原型table

__index元方法不必一定是一个函数,还可以是一个table。
当它使一个函数时,lua以table和不存在的key座位参数来调用该函数,而当它是一个table时,lua就以相同的方式来重新访问这个table。

调用rawget(t,i)就是对table t进行了一个 原始的raw 访问,不考虑元表。


__index用于table的更新,而__newindex用于table的查询。

当一个table中不存在的索引赋值时,解释器就会查找__newindex元方法。如果有这个元方法,解释器就调用它,而不是执行赋值。如果这个元方法是一个table,解释器就在这个table中执行赋值,而不是对原来的table。

调用rewset就可以绕过元方法。

模块 包

一个模块就是一个程序库,可以通过require来加载,然后得到一个全局变量,表示一个table。这个table就像是一个名称空间,其内容就是模块中导出的所有东西,如函数和常量。

如果模块已经加载,就返回相应的值
加载模块
1. 首先通过package.loaded判断该模块是否已经存在
2. 通过package.preload判断preload是否存在,
3. 通过package.path查找lua文件
4. 通过package.cpath查找c库
5. 以第一个”.”为分割,将模块名划分为:(main, sub)的形式,根据package.cpath查找
6. 通过loadfile来加载该文件,如果是c程序库,就通过loadlib来加载
7. 只有第一次加载时会执行(要每次都执行可以使用loadfile)

    --判断是否加载
    local isLoaded = package.loaded[filename]
    --重新加载 例如热更新
    package.loaded['foo'] = nil
    require "foo"

局部变量

尽可能使用局部变量,
1. 加快访问速度
2. 避免将一些无用的名称引用全局变量,搞乱了全局变量

创建局部变量来保存全局变量

    local foo = foo

如果后续其他函数改变了全局变量foo的值,也可以起到临时保存的作用

错误处理

手动抛出错误

    error("")

断言

    assert(name == “a”,”error”)

类似try catch

    local status,err = pcall(test)
    if status then
        --正常
    else
        --异常
    end

闭合函数

一个函数加上改函数所需访问的所有非局部变量

    function count()
        int i = 1;
        return function()
            i  = i + 1
            return i
        end
    end

尾调用

一个函数的调用是另一个函数的最后一个动作时,这个调用就称之为尾调用。

function mute()
    return count() //是
    return count() + 1// 不是
end

有点,不会销毁多余的栈空间

杂记

如果你想删除一个全局变量,只需要将变量赋值为nil

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

lua执行的每段代码,例如一个源代码文件或在交互模式中输入的一行代码,都成为一个程序块

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值