`
xidajiancun
  • 浏览: 454425 次
文章分类
社区版块
存档分类
最新评论

Lua 闭包快速入门

 
阅读更多

示例代码

local function x()
    local a = 1

    local function y()
        print(a)
    end
    if 1 > 0 then
        local function z()
        end
    end
    a = 2
    y()
    -- z() -- will fail, function not found
end

x()

讲解

闭包(closure)是一个在高级语言中比较通用的概念,理解闭包之后写代码可以事(tí)半(shēng)功(bī)倍(gé)。我学习闭包这个概念时,看到的都是生涩、难懂、冗长的例子,在经过自己的实践领悟之后,我写了上面这一小段示例代码,用来讲解闭包。相信有任何一门语言基础的人都能轻松看懂这十多行代码。这就是为什么我要重新造这个轮子。
简单来说:

函数 = 抽象
闭包 = 抽象 + upvalue + env

所以,闭包与传统的『函数』概念基本相似,只是比函数多两个特性:upvalue和env。

upvalue
看上面的例子,变量a就是一个upvalue。在函数y()中打印了变量a,而实际上函数y()并没有定义任何传入参数。y()能够引用到函数外面的变量a,这样的变量就叫upvalue。所以闭包的好处是,你不必声明一堆传入参数,就可以在函数内直接读写upvalue。
env
例子中定义了3个函数x() y() z(),其中y()和z()是在x()的内部定义的,这就是闭包的灵活性,可以简单理解成:函数可以嵌套函数,一层包着一层。在传统的编程语言中,即使是子函数,也是必须要在外面定义的。env指的是环境,也就是变量和函数的作用范围/生存期。理解了env,就真正理解了闭包,才明白哪些变量是可以当做upvalue引用的,哪些内部函数是可以调用的。
函数y()的作用范围是,从y()的定义开始,一直到包着它的函数x()定义结束,都是y()的作用范围,在这期间都可以调用到y(),所以代码中y()的调用是可以正常执行的。函数z()的作用范围是,从z()的定义开始,一直到包着它的if .. end语句就结束了,所以代码中注释起来的z()调用,实际执行起来,会报错找不到这个函数。
变量a的作用范围从变量a的定义开始,一直到包着它的函数x()定义结束,所以x()内的每一个地方都可以引用到a,包括y()和z()的里面。

执行结果

这段代码是可以执行的,执行的结果,也就是a的值打出来是1还是2?
这里的执行顺序是:首先a被赋值为1;然后定义了函数y(),这时候y()是不会执行的,因为并没有调用;然后a被赋值为2;然后调用了函数y(),这时候y()被执行,输出当前a的值,结果是2。

Lua只有闭包

实际上,Lua所有的函数都是闭包,也就是说,Lua只有闭包,而没有传统意义的函数,所以在所有Lua代码中,你都可以自由地使用这个特性,轻松地减少胶水代码

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics