Lua闭包,词法定界,第一类型值笔记

本文深入解析Lua中的闭包概念,包括函数作为第一类型值、词法定界、闭包的应用场景如创建迭代器、作为高阶函数参数及重新定义函数。通过实例展示了闭包如何保留非局部变量状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Lua支持闭包的语法特性:

1.函数是第一类型值:第一类型值表示函数与其他传统类型的值(例如数字和字符串类型)具有相同的权利。即函数可以存储在变量中,可以作为实参传递给其他函数,还可以作为其他函数的返回值。以下两种定义函数的方式是等价的:

    local function f1()
        print("Hello")
    end
    --等价于
    local f1 = function()
        print("Hello")
    end

2.词法定界:Lua中函数可以访问函数之外定义的值,该值可以定义在其他函数内,也可以直接定义在文件之内。该值叫做此函数的非局部变量或upvalue。通过下面例子可以看出函数可以对非局部变量的正确访问。

--f1访问未被定义在函数中的num
 local num = 0
 local function f1()
     print(num)
 end
 f1()--输出0

 --f3访问被定义在f2函数中的count
 local function f2()
     local count = 5
     local function f3()
         print(count)
     end
     f3()
 end
 f2()--输出5

3.闭包概念:Lua函数在多次调用时,可以正确访问他上次使用的非局部变量的值,这样的语法特性叫闭包。

广义来说,只要用到了外部定义的变量的函数,就使用了闭包特性。

通过下面例子可以看出函数多次调用时,上次使用的非局部变量的值得以保留。

--f1访问未被定义在函数中的num
local num = 0
local function f1()
    num = num + 1
    print(num)
end
for i=1,3,1 do
    f1()--输出1,2,3
end

--f3访问被定义在f2函数中的count
local function f2()         
    local count = 5
    local function f3()
        count = count + 1
        print(count)
    end
    for i=1,3,1 do
        f3()--输出6,7,8
    end
end
f2()

4.闭包应用:(只要出现了使用非局部变量的函数,就用了闭包)

4.1 在返回值是函数的函数中起到作用,比如创建迭代器,示例:

    local function myIpairs(t)
        local index = 0
        local function f1()
            index = index + 1
            return index, t[index]
        end
        return f1
    end
    local color = {"red","blue","yellow","orange","black"}
    local iter = myIpairs(color)
    while true do
        local k,v = iter()
        if v then
            print(k,v)
        else
            break
        end
    end

4.2 作为高阶函数(比如table.sort)的参数,且需要访问外部定义的变量。

    local names = {"Peter", "Paul", "Mary"}
    local grades = {Peter = 8, Paul = 7, Mary = 10}
    for k,v in ipairs(names) do
        print(v)
    end
    table.sort(names, function(n1,n2)
        return grades[n1] > grades[n2]--grades为非局部变量,使用闭包
    end)
    print("--- after sort ---")
    for k,v in ipairs(names) do
        print(v)
    end

4.3 用来重新定义函数,重定义时需要使用原来的函数。

    local str = "galaxy"
    local oldLen = string.len
    function string.len(str)
        local len = oldLen(str)--oldLen为非局部变量,使用闭包
        print(str .. " length: " .. len)
        return len
    end
    local len = string.len(str)--打印出galaxy length: 6

面试环节

问:Lua中闭包的概念是什么?

答:举例来说,有一对有嵌套关系的函数,外包函数叫f1,内嵌函数叫f2,f1内f2外定义一个局部变量a,a叫做f2的非局部变量,每次调用f2时不会重置a的语法特性叫做闭包。闭包可以用来创建迭代器,作为高阶函数的参数以及重新定义已存在的全局函数等作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ellis1970

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值