lua系统学习12-深入函数

19 篇文章 0 订阅
14 篇文章 0 订阅

在这里插入图片描述
Closure 闭合函数
table的排序方法就是用到了这种函数,匿名函数。
示例

names={"Miracle","Jack","xiaosha"}

grades={Miracle=6,Jack=2,xiaosha=3}
for i,v in ipairs(names) do
    print(i,v)
end
t=table.sort(names,function(name1,name2)
    return grades[name1]<grades[name2]
    end)
for i,v in ipairs(names) do
print(i,v)
end
1	Miracle
2	Jack
3	xiaosha
1	Jack
2	xiaosha
3	Miracle

table.sort 需要两个参数{arg1=要排序的列表,arg2=一个返回值为boolean的函数 }
上面示例中使用了匿名函数,直接写在了参数列表内部。
table.sort内部会调用这个函数,根据函数的返回值来判断前一个和后一个的值 要大于还是要小于的条件进行排序。
它总是以返回值结果为false作为去对换前后者的依据。那么概况意思就是说我想要让所有后者都大于前者,就是从小到大排序
以上面示例来看,grades[name1]<grades[name2]
name1是前者 name2是后者 每次会向后迭代 下一次判断就是name2 与name3
我们通过grades的构造可以知道name1>name2
grades[name1]<grades[name2]=false 故需要对换。

在上面案例中,我们还发现这样的匿名函数竟然可以取得grades。
这是函数本身就是写在grades主体下的,且直接取得地址,后面即使主体的域结束,该函数依然可以保存对grades的引用。

看下例:

function Func2()
    local localVariable;
    if not localVariable then
        localVariable=0;
    end
    return function()   localVariable=localVariable+1 return localVariable end
end
varFunc=Func2()
print(varFunc())
print(varFunc())
print(varFunc())

输出:

1
2
3
function Func2()
    local localVariable;
    if not localVariable then
        localVariable=0;
    end
    return function()   localVariable=localVariable+1 return localVariable end
end
varFunc=Func2()
print(varFunc())
print(varFunc())
print(varFunc())
varFunc=Func2()
print(varFunc())
print(varFunc())
print(varFunc())
1
2
3
1
2
3

通过上面两个测试 我们发现 这里的i在匿名函数中并不是局部变量也不是全局变量,我们叫他非局部变量。它每次都会续上一次调用结束后的i;但是下一次调用了Func2 它又从头开始了。
说明i在func2是局部函数,会随域结束被销毁。但在匿名函数中又把这个属于func2的局部函数存在Closure的栈中,这样虽然在func2结束了销毁对func2的引用,但是Closure中还有对i的引用。
那么什么是Closure呢,所谓Closure就是该函数和它所需要的所有非局部变量。
简单地讲就是一个closure就是一个函数加上该函数所需访问的所有非局部变量。如果再次调用Func2,那么就会创建一个新的局部变量i,从而得到一个新的closure。

引用Lua程序设计第二版内容
在这里插入图片描述

函数覆盖

function funcName()
    dofile("C:\\File\\Lua\\Closure2.lua")
    print(notLocalVar())
    print(notLocalVar())
end
funcName()
funcName=function() print( "test")  end
funcName()
HelloWorld
1
2
test

function funcName()
    dofile("C:\\File\\Lua\\Closure2.lua")
    print(notLocalVar())
    print(notLocalVar())
end
funcName()
function funcName()
print( "test")
end
funcName()

两种方法都可以。

通过这种方法与Closure,Lua还可以构建一个安全的环境;
用非局部变量暂存原有方法,而使用匿名函数重构覆盖原有方法,在原有函数中设置受限条件,只有符合条件去访问这个非局部变量调用原有的方法。看代码
在这里插入图片描述
在这里插入图片描述

非全局的函数

函数不仅可以存储在全局变量中,还可以存储在table的字段中和局部变量中。**只要将一个函数存储到一个局部变量中,即得到了一个局部函数 也就说该函数只能在某个特定的作用域中使用。
简单来说就是在一个程序块(Chunk)**中定义的函数就是局部函数
使用Table来存放函数的几种方法

function tableSaveFunc()
    function tableSaveFuncMethod1()
        t={}
        t.a=function(name,description) return "名字","描述"  end
        t.b=function(arg,sex)  return  "年龄","性别"  end
        print(t.a())
        print(t.b())
    end
    tableSaveFuncMethod1()
    function tableSaveFuncMethod2()
        t={}
       function t.a(name,description) return "名字","描述"  end
        function t.b(arg,sex)  return  "年龄","性别"  end
        print(t.a())
        print(t.b())
    end
    tableSaveFuncMethod2()
    function tableSaveFuncMethod3()
        t={a=function(name,description) return "名字","描述"  end,b=function(arg,sex)  return  "年龄","性别"  end}
        print(t.a())
        print(t.b())
    end
    tableSaveFuncMethod3()
end
tableSaveFunc()
名字	描述
年龄	性别
名字	描述
年龄	性别
名字	描述
年龄	性别

可以看到tableSaveFuncMethod2这个方法有点特殊。
它是直接在定义函数时候 指定列表索引变量作为函数地址的存放位置。
当然局部函数可以显示的去定义

function localFunc()
local f=function()
    print(1,2,3)
end
    function gg()
        f()  end
    gg()
    f()
end
localFunc();
1	2	3
1	2	3

虽然局部函数可以显式的去定义,但是我觉得没必要,因为局部函数与局部变量还有点不同,变量在方法中如果没定义local 他就是全局的,但是函数的话,如果一个函数在块中,lua会自动把这个函数判定为局部函数。所以这么看显式得定义局部函数 就显得有点多余了。

function variableLocal()
wsdf=1
end
variableLocal()
print(wsdf)

除此之外局部函数的定义还可以这样写

    local function aaa()

    end

在使用一个局部变量去初始化接收一个函数的时候,可能会发生一个问题。

function  localVariableRefFunc()
    local f=function(n)
        if n==0 then
            return 1
        else
            return n*f(n-1)
        end
    end
    print(f())
end
localVariableRefFunc()

在上面这个示例中,编译器发生了报错,具体原因是因为 在等号赋值符右侧的表达式优先去计算,最后才会计算等号左边的。
也就是说 当我们函数中用到了f的时候,其实局部变量f还没有初始化,还没有去接收当前这个函数。那么我们在函数中定义的这个f其实引用的是一个全局变量f的地址 值为nil。
修改之后

function  localVariableRefFunc()
    local f=nil
    f=function(n)
        if n==0 then
            return 1
        else
            return n*f(n-1)
        end
    end
    print(f(10))
end
localVariableRefFunc()
3628800

当然 我们还知道局部函数另外一种定义

function  localVariableRefFunc()

    local function f(n)
        if n==0 then
            return 1
        else
            return n*f(n-1)
        end
    end
    print(f(10))
end
localVariableRefFunc()

所以我们在lua中我们也可以把函数名理解为 是一个变量。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值