Lua深入函数类型,以及内存管理

前言

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

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

猜你喜欢

转载自blog.csdn.net/liaoshengg/article/details/81327114