博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lua的闭包详解(终于搞懂了)
阅读量:4081 次
发布时间:2019-05-25

本文共 1695 字,大约阅读时间需要 5 分钟。

词法定界:当一个函数内嵌套另一个函数的时候,内函数可以访问外部函数的局部变量,这种特征叫做词法定界

table.sort(names,functin (n1,n2)        return grades[n1]>grades[n2]    end)    //内部匿名函数可以访问外部函数的n1,n2

第一类值:lua当中函数是一个值,他可以存在变量中,可以作为函数参数,可以作为返回值

function test()        local i=0        return function()            i++            ...        end    end    //函数作为返回值,这里的i也叫外部局部变量,就是lua中的upvalue

 

闭包:通过调用含有一个内部函数加上该外部函数持有的外部局部变量(upvalue)的外部函数(就是工厂)产生的一个实例函数

闭包组成:外部函数+外部函数创建的upvalue+内部函数(闭包函数)

实例:

function test()        local i=0        return function()//尾调用            i+=1            return i        end    end    c1=test()    c2=test()//c1,c2是建立在同一个函数,同一个局部变量的不同实例上面的两个不同的闭包            //闭包中的upvalue各自独立,调用一次test()就会产生一个新的闭包    print(c1()) -->1    print(c1()) -->2//重复调用时每一个调用都会记住上一次调用后的值,就是说i=1了已经    print(c2())    -->1//闭包不同所以upvalue不同        print(c2()) -->2

 

闭包在迭代器中的运用:迭代器需要保留上一次调用的状态和下一次成功调用的状态,刚好可以使用闭包的机制来实现

创建迭代器:(一定要注意迭代器只是一个生成器,他自己本身不带循环)

     function list_iter(t)            local i=0            local n=table.getn(t)            return function()                i=i+1                if i<=n then return t[i] end            end        end    //这里的list_iter是一个工厂,每次调用都会产生一个新的闭包该闭包内部包括了upvalue(t,i,n)    //因此每调用一次该函数产生的闭包那么该闭包就会根据记录上一次的状态,以及返回list的下一个

使用迭代器:

while中使用:            t={10,20,90}            iter=list_iter(t)//调用迭代器产生一个闭包            while true do                local element=iter()                if element==nil then break end                print(element)                end            end        泛型for使用:            t={10,0,29}            for element in list_iter(t) do//这里的list_iter()工厂函数只会被调用一次产生一个闭包函数,后面的每一次迭代都是用该闭包函数,而不是工厂函数                print(element)            end

posted on 2018-08-08 10:17 阅读(...) 评论(...)

转载地址:http://jgvni.baihongyu.com/

你可能感兴趣的文章
.net强制退出主窗口的方法——Application.Exit()方法和Environment.Exit(0)方法
查看>>
c# 如何调用win8自带的屏幕键盘(非osk.exe)
查看>>
build/envsetup.sh 简介
查看>>
Android framework中修改或者添加资源无变化或编译不通过问题详解
查看>>
linux怎么切换到root里面?
查看>>
linux串口操作及设置详解
查看>>
安装alien,DEB与RPM互换
查看>>
编译Android4.0源码时常见错误及解决办法
查看>>
Android 源码编译make的错误处理
查看>>
linux环境下C语言中sleep的问题
查看>>
ubuntu 12.04 安装 GMA3650驱动
查看>>
新版本的linux如何生成xorg.conf
查看>>
xorg.conf的编写
查看>>
启用SELinux时遇到的问题
查看>>
virbr0 虚拟网卡卸载方法
查看>>
No devices detected. Fatal server error: no screens found
查看>>
新版本的linux如何生成xorg.conf
查看>>
virbr0 虚拟网卡卸载方法
查看>>
Centos 6.0_x86-64 终于成功安装官方显卡驱动
查看>>
Linux基础教程:CentOS卸载KDE桌面
查看>>