精华内容
下载资源
问答
  • lua闭合函数

    2016-07-11 23:26:00
    lua 闭合函数:一个函数加上该函数所需访问的所有“非局部变量”。 如上所示:count()函数返回了另一个函数,而这个函数使用了count()函数中的局部变量。当该函数被调用时,count()函数中的局部变量不会被重置...
    function count( ... )
        local i = 0
        return function( ... )
            i = i+ 1
            return i
        end
    end
    
    local  func =  count(...)
    
    print(func())
    print(func())
    print(func())

    结果如下:

    1
    2
    3
    [Finished in 0.1s]

    lua 闭合函数:一个函数加上该函数所需访问的所有“非局部变量”。

    如上所示:count()函数返回了另一个函数,而这个函数使用了count()函数中的局部变量。当该函数被调用时,count()函数中的局部变量不会被重置。

    此局部变量类似于c++中静态局部变量。

     

    转载于:https://www.cnblogs.com/guoliangjun/p/5662032.html

    展开全文
  • 1. lua闭合函数 闭合函数在lua中指的一个函数以及该函数需要访问的所有的非局部变量,其中该函数是一个内部匿名函数,非局部变量相对于局部变量和全局变量而言,不同之处是该局部变量定义后,会被其他函数调用...

    1. lua闭合函数

    闭合函数在lua中指的一个函数以及该函数需要访问的所有的非局部变量,其中该函数是一个内部匿名函数,非局部变量相对于局部变量和全局变量而言,不同之处是该局部变量定义后,会被其他函数调用(内部匿名类调用)

    例如:

    function count()
        local i = 0;--非局部变量
        return function()--匿名内部类
                  i = i + 1;
                  return i;
               end
    end
    调用时:

    local func = count()

    print(func()) --输出1

    print(func())--输出2

    print(func())--输出3

    用法:lua回调函数、重新定义某些函数

    for i=1 ,6 do
    		local temp = i --非局部变量
    		
    		table.insert(self.btn_list, self.shapeNode:getCCSWidgetByName(string.format("Button_%s", i)))
    		local func = function() --内部函数
    			local flag = 0
    			for i,v in ipairs(game_app.fairy_detail_info.fairycard_list) do
    				if GameConfig.CnfFairyCard[temp].stuff_id == v.CardId then
    					flag = 1
    				end
    			end
    			--点击变身卡之后设置按钮状态
    			if flag == 0 then
    				self.activate_btn:setVisible(true)
    				self.activate_btn:setEnabled(true)
    				self.fairyshape_btn:setVisible(false)
    				self.fairyshape_btn:setEnabled(false)
    			elseif flag == 1 then
    				self.activate_btn:setVisible(false)
    				self.activate_btn:setEnabled(false)
    				self.fairyshape_btn:setVisible(true)
    				self.fairyshape_btn:setEnabled(true)
    			end
    			--点击变身卡后将该卡id赋值给全局变量event	
    			self.event = temp
    		end
    		self.btn_list[i]:SetLuaCallBack(0, 0, GameLib.AddCallBackFunc(func), 0)--回调函数
    end

    2.lua尾调函数

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

    lua中保存函数的栈长度是一定的,如果无限次的调用类似Java、c++语言之中的回调函数的概念,lua栈会溢出。尾调时会消除当前栈而转到其他函数,从而避免递归时栈溢出,可以有效减少栈的开消,减轻函数调用的层次

    function mutou()--尾调用
        return count();
    end
    function mutou()--非尾调用
        return count() + 1;
    end
    
    
    function foo(n)
        if n > 0 then
            return foo(n - 1);
        else
            return "end";
        end
    end

    print(foo(99999));--不会溢出

    
    
    function foo(n)
        if n > 0 then
            return foo(n - 1);
        else
            return "end";
        end
    end
    print(foo(99999));--会溢出

    
    
    



    展开全文
  • 闭合函数: 函数A中包含另一个函数B,函数B中使用了非局部变量(函数中A的局部变量),构成闭合函数 影响:延长了非局部变量(A函数中局部变量)的生命周期 简单说就是一个函数 return了一个匿名函数,匿名函数里又...

    前言

    Lua的函数有多种使用方法 ,因为Lua内存遵循C内存管理

    一、闭合函数:”非局部变量生命周期受影响”

    闭合函数: 函数A中包含另一个函数B,函数B中使用了非局部变量(函数中A的局部变量),构成闭合函数
    影响:延长了非局部变量(A函数中局部变量)的生命周期

    简单说就是一个函数 return了一个匿名函数,匿名函数里又外部函数的局部变量

    function functionB()
        local AA = 10
        return function()
            AA = AA + 2
            return AA
        end
    end
    
    print(functionB) -- 地址不同(肯定是不同)
    num2 = functionB() 
    print(functionB()) -- 返回函数的地址
    
    print(num2)  -- 地址不同了,因为这个是FunctionB上的局部变量的内存地址
    print(num2())--12
    print(num2)  -- 地址和第一个num2一样不变
    print(num2())--14
    print(num2)  -- 地址和第一个num2一样不变
    print(num2())--16
    print(num2)  -- 地址和第一个num2一样不变
    
    print(functionB())
    num2 = functionB() -- 重新释放调用函数
    print(num2()) -- 12
    
    --说明闭合函数的匿名函数内有外函数的局部变量,
    --这个局部变量因为在外部函数中,
    --就算调用了多次匿名函数,外部函数没有释放,外部函数的局部变量就不会释放 

    二、非闭合函数

    非闭合函数:局部变量生命周期不受影响
    简单说就是函数return一个匿名函数,匿名函数返回匿名函数里的局部变量

    unction functionA()
        return function()
            local  AA = 1
            AA = AA + 2
            return AA
        end
    end
    
    num1 = functionA()  -- 这样num1实际就是那个匿名了
    num1()
    print(num1()) -- 3
    print(num1()) -- 3
    print(functionA()) -- 函数地址
    print(num1) -- 函数地址数值同上,说明共用了那个函数内存
    print(num1()) -- 3

    Lua内存管理

    Lua内存遵循C内存管理

    栈:由编译器管理 局部变量,形参,声明变量开辟空间、函数结束内存回收
    堆:由程序员管理、使用函数malloc开辟的空间,不用malloc就一定在栈上,lua几乎不用堆内存,就在栈上用全局变量,堆内存需要free释放,该区域内存必须由指针进行操作(开辟,回收)
    全局存储区:由编译器管理全局变量,声明的时候开辟空间,程序结束释放
    静态存储区:由编译器管理用static修饰,声明变量开辟空间,程序结束释放
    常量存储区:由编译器管理,用const修饰,声明变量开辟空间,看具体生命周期释放

    非全局函数

    非全局函数也就是用局部变量修饰符修饰的方法类型变量

    local num3 = function()
        print("local Function")
    end
    num3()
    
    local num4
    num4 = function( ... )
        print("local function2") 
    end
    num4()
    

    上面2种方法都是非全局函数,但是也有区别,就是他们的执行次序必须是从上到下的了
    可以理解成c语言的函数调用次序一样,如果没有先声明函数名,直接写函数,那么在Main函数下面的函数不能被Main函数调用。

    这里先声明局部,就可以在上面函数里调用下面的函数(无视次序)

    
    local num5
    local num6 
    
    num5 = function( ... )
        num6(10,20)
    end
    
    num6 = function( a,b )
        print(a+b)
    end
    
    num5()
    

    如果不先声明,那么应该把先被调用的函数写在使用这个函数的上面(从上到下的编译次序)

    local num6 = function ( a, b )
        print(a+b)
    end
    
    local num5 = function( ... )
        num6(10,20)
    end
    
    num5()

    尾调用

    使用的情况:
    一个函数的调用,是另一个函数的最后一个动作

    local funcA
    local funcB
    
    funcA = function()
    return funcB()
    end
    
    funcB = function(  )
        print("最后进行的方法")
    end
    
    funcA()
    

    只能return一个方法,不能再添加别的东西如 return func + 1

    尾调用有什么好处?
    尾调用的时候,该函数也就意味着结束了,不需要保存任何关于该函数的栈信息,
    因此可以拥有无数嵌套尾调用。尾调用主要用来实现状态机等操作。

    展开全文
  • Lua函数以及闭合函数的理解

    千次阅读 2015-09-25 12:05:00
    Lua闭合函数学习笔记和自己的感悟。

            在读Lua程序设计这本书时,前五章我是抱着鄙视的态度去读的。因为那些被我称为奇淫巧计的语言写法,让我颇不以为然。但是从第六章的深入函数开始,逐渐转变了我对Lua的态度。不吐不快,Lua不愧为天下第一脚本。在Code武林中,众语言好比各武学深渊的正派绝技,而Lua好似天下第一暗器。言归正传,记录一下函数和closue闭合函数的思想。

    词法域和第一类型

             在C/C++,C#或者Java等传统语言中,一个函数A,如果想调用另一个函数B,并且B需要访问A中的变量,那么A就需要向B传递参数,参数形式可以是普通类型,指针,或者引用。(C#中有out输出参数和ref引用,专门的关键字来做这件事)但是在Lua中,呵呵,不必如此。

             Lua中有一个“词法域”的概念。即B可以访问他所需要访问的所有“非局部变量”(后面会解释为什么叫双引号下的非局部变量)。但是这一切的说说笑笑都必须要有前提——在Lua中,函数是“第一类型”。就是说函数和int,string,float等泛泛之辈一样,都TM是类型,都是菜。而函数名则可以理解为,拿着函数实体的变量。请看下面这个例子:

    a = {p = print}
    a.p("hello bitch")		        ---hello bitch
    print = math.sin			---'print'现在是正弦函数
    a.p(print(1))				---0.8414709848079
    sin = a.p				---'sin'现在是print函数
    sin(10 .. 20)				---1020


    正所谓似鸡非鸡,似鸭非鸭。鸡有可能变鸭,鸭也可以手术变鸡。

    那么说函数是变量,他还就蹬鼻子上脸,给变量一会看看——Lua常见的函数编写方式:

    function foo(x)  return  2*x  end

    其实他是一下这句话的简化形式:

    foo = function (x)  return  2*x  end

    所以,一个函数的定义实际就是一条赋值语句,这条语句首先创建一个函数类型的值,然后将这个值赋予这个函数变量。也可以将表达式    function(x)<body>end  理解为一种函数的构造式。就像table的构造式 {} 一样。

    将这种函数构造式的结果称为一个“匿名函数”。下面这个例子就是使用匿名函数来做参数。


          table.sort,是对一个table表中的内容按照一定规则排序。但是sort并没有提供具体的规则,规则的指定完全交给使用者自己定义。升序,降序,按key顺序等等。sort接收两个元素,第一个元素是table,第二个元素就是排序规则。那我们在这里就用匿名函数来做这个sort的第二个元素——排序规则。

    network = {
    {name = "grauna", NICK = "lululala"},
    {name = "araadd", NICK = "bababu" },
    {name = "oo", NICK = "ppreea"},
    {name = "zzdafae", NICK = "ddadf"},
    }
    for i=1, #network do
    	print(network[i].name)
    	end
    	
    table.sort(network, function(a,b) return (a.name > b.name) end)
    
    for k,v in pairs(network) do
    	print(k,v.name)
    	end



    二、闭合函数

            在理解了上面这些思想之后,我们来想想closure。还是刚才说的, A==>>B,A是B的外部函数,B可以访问A中的局部变量。直接上菜说:

    names = {"Peter", "Paul", "Mary"}
    grades = {Mary = 10, Paul = 7, Peter = 8}
    table.sort(names, function(n1, n2)
    	return grades[n1] > grades[n2] 
    	end)
    
    for k,v in ipairs(names) do
    	print(k,v)
    end


    用一个单独的函数来调用:

    names = {"Peter", "Paul", "Mary"}
    grades = {Mary = 10, Paul = 7, Peter = 8}
    function sortbygrade(names, grades)
    	table.sort(names, function(n1, n2)
    	return grades[n1] > grades[n2] 
    	end)
    	return names
    end
    
    	for k,v in ipairs(sortbygrade(names, grades)) do
    	print(k,v)
    	end

    输出结果同上。

    可见,传递给sort的匿名函数可以访问参数grades,而grades是外部函数sortbygrade的局部变量。而在这个匿名函数内部,grades既不是全局变量也不是局部变量,将其称为一个“非局部的变量”。

    再看下面这个例子:

    function newCounter()
       local i =  0
       return function()
       i = i + 1
       return i
      end
    end
    c1 = newCounter()
    print(c1())			---1
    print(c1())			---2
    c2 = newCounter()
    print(c2())			---1
    print(c1())			---3
    print(c2())			---2

    初次见到这个输出结果,有些摸不到后脑勺。为啥第二次print(c1())结果是2呢?

    仔细一想,这还得说那句老话,Lua中函数是第一类型。(别骂娘)

    你想想,在C++中,如果你定义一个int a=1;那么编译器只会在栈中开辟一块空间来存a,直至释放。

    那么c1也是这回事儿,你第二次print,实际上还是在  第一次在栈中开辟的那块空间里  折腾。所以此时栈中的local i已经不是当年那个 = 0 的小姑娘了,人家已经长成 1 了。所以你再print,就在1的基础上变成2了。

    而c2跟c1不一样,c2是隔壁家的姑娘,又是一块栈空间,所以c2的第一次还是1。 以此类推,后面的print结果就顺理成章了。


    在下一篇中,我会介绍pairs和ipairs的区别。


    展开全文
  • Lua学习之闭合函数

    2018-04-10 15:39:49
    闭合函数(closure) 看Lua程序设置这本书的时候,其实感觉也就Lua也就那样,直到看到闭合函数这一个块 首先来说说函数,函数在lua中属于第一类值, 其实对于函数而言,function a() ... end 和 a = function()......
  • lua函数具有两大特征:函数作为第一类值,函数具有特定的词法域(Lexical Scoping) 所谓第一类值:代表函数和其他传统类型的值是等价的(例如数字和字符串),函数可以同他们一样存储在变量,table中,可以作为...
  • 上一篇我们简单地介绍了Lua的函数,这次,我们来点特别的,来介绍一下Lua的函数(小若:等等,我...闭合函数(closure)理论上来说,Lua的所以函数都应该称之为闭合函数,但是,这种反人类的做法,我们还是抛弃吧~
  • 【笨木头Lua专栏】基础补充03:闭合函数、非全局函数与函数的尾调用 笨木头2014-08-15 21:26 Cocos2d-x Lua阅读(4,368) 9条评论 上一篇我们简单地介绍了Lua的函数,这次,我们来点特别的,来介绍一下Lua的函数...
  • 对于闭合函数而言,属于它的非局部变量i,并不是再调用它的时候临时产生的,而是和它一起存在的,所以每次调用闭合函数,非局部变量的值都不会被会重置 。 如果大家还是不太清楚,那么,我们给这个闭合函数添加一...
  • Lua基础 函数(二)

    2015-09-18 11:35:26
       Lua基础 函数(二) 分类: ...闭合函数非全局函数强大的尾调用 在Lua中,你可以像使用number和string一样使用function。可以将function存储到变量中,存储到table中,可以当作函数
  • 词法域:若将一个函数写在另一个函数之内,那么这个位于内部的函数便可以访问外部函数中的局部变量,这项特征称之为“词法域”。例:假设有一个学生姓名的列表和一个对应于没个姓名的年级列表,需要根据每个学生的...
  • 若将一个函数写在另一个函数之内,那么这个位于内部的函数便可以访问外部函数的局部变量。function newCounter()local i = 0return function()----匿名函数 i = i + 1 return i endendc1 = newCounter()c2 = ...
  • lua基础学习 - 闭合函数(closure)

    千次阅读 2012-09-25 22:02:06
    1. lua中的函数是“第一类值”,就是说函数和整数,字符串这些是一样的,都可以保存到变量中,看上面第一句的声明。 2. 一个closure就是一个函数加上它访问的所有“非局部的变量”。上例中内部函数counter...
  •  从技术上讲,Lua中只有closure而不存在“函数”,因为函数本身就是一种特殊的closure【closure:指一个函数以及一系列这个函数会访问到“非局部的变量”,因此若一个closure没有那些会访问的“非局部变量”,那他...
  • lua函数

    2014-08-30 00:14:33
    第一类值:函数可以存储到变量中,可作为实参传递,还可以作为函数返回值。 词法域: 函数可以嵌套,内部的函数可以访问外部函数中的变量。...closure闭合函数: function sortbygrade ( names, grades) ...
  • Lua代码: human = { age = 0, __newindex = function (t,k,v)if(k == "age") thenprint("age 变化了")human.age = velseprint("其他属性变化了")end end} coco = { --age = 0} setmetatable(coco,human)human.__i...
  • 主要介绍了Lua教程(四):函数详解,本文讲解了多重返回值、变长参数、具名实参、闭合函数、匿名函数、非全局函数等内容,需要的朋友可以参考下

空空如也

空空如也

1 2 3 4
收藏数 63
精华内容 25
关键字:

lua闭合函数