网站开发前景咋样,用Docker搭建WordPress博客,常见的静态网页,南宁横县网站建设推广文章目录 函数函数嵌套闭包Closures可变函数函数重载 函数
函数嵌套
function A()print(这里是函数A)return function ()print(返回函数不要起名)end
end
B A()
B()输出#xff1a;
这里是函数A
返回函数不要起名使用函数嵌套的用法#xff0c;我… 文章目录 函数函数嵌套闭包Closures可变函数函数重载 函数
函数嵌套
function A()print(这里是函数A)return function ()print(返回函数不要起名)end
end
B A()
B()输出
这里是函数A
返回函数不要起名使用函数嵌套的用法我们可以将另一个函数作为返回值但是返回函数作为一个值是要被赋值给其他变量的所以return时不能起名赋值为其他变量名。 闭包Closures
推荐阅读深入Lua函数和闭包
在函数嵌套中我们需要接触一个叫做闭包的概念
这就是一个闭包它由一个函数和该函数会访问到的非局部变量或者说upvalue组成
function f1(n)--函数参数n也是局部变量local function f2()print(n) --引用外部函数的局部变量即upvalueendreturn f2
enda f1(1) --注意,闭包不传入参数则为nil
a()当一个函数内嵌套另一个函数的时候内函数可以访问外部函数的局部变量这种特征被称为词法域什么意思呢
例如上述f1的入参n它是一个形参也是f1内的局部变量。现在f1内部定义了另一个函数f2显然f2需要访问f1内的局部变量 n。但是对于n而言它的词法域或者说作用域只是在f1内。如果只是简单的函数嵌套的话用其他语言可以是这样实现的
void f1(int x){f2(x)
}
void f2(int x){return x
}但是问题是上述定义中f1内的x和f2内的x并不是同一个x而分别是它们作用域内定义的局部变量。
而闭包更相当于一个指针使得f2直接引用了f1的局部变量
#include iostream
using namespace std;
void f2(int *x)
{printf(%d, *x);
}
void f1(int x)
{f2(x);
}
int main()
{int i 1;f1(i);return 0;
}这就是闭包的概念内部函数innerFunction能够访问并持有其外部函数outerFunction作用域中的变量这些被内部函数引用的外部函数的局部变量被称为upvalues。实际上一般的函数在lua中是一种特殊的闭包。整个函数产生的闭包类似于下列struct
// Lua闭包
typedef struct LClosure {ClosureHeader;struct Proto *p; // 函数原型UpVal *upvals[1]; /* list of upvalues */ // upvalue列表
} LClosure;function Create(n)local function f1()print(n)endlocal function f2()n n 10endreturn f1,f2
end
a,b Create(10)
a() -- 10
b()
a() -- 20
b()
a() -- 30在上述闭包中两个闭包f1f2使用的n是同一个局部变量因此f2使n增加后f1输出值也变了。它们共享一个upvalues。
现在假设要创建一个对象对外只提供有限的访问接口而对象内部的数据不能直接被修改那么我们可以这样写
local function new_object()local obj { -- 这就是要创建的对象_data1 1, -- 假设这是内部数据_data2 2, -- 这是外部可修改的数据}return { -- 这是返回的接口tableget_data2 function() return obj._data2 end,set_data2 function(value) obj._data2 value end,}
endlocal obj_inteface new_object()
obj_inteface.set_data2(100)
print(obj_inteface.get_data2()) -- 100可变函数
function f1( x,...)arg{...}for i1,#arg doprint(arg[i])end
end我们用…表示参数是可变参数它能接收任意长的参数但是在我们使用的时候最好使用一个table来接收这个可变参数。此外其他固定的入参一定要放在可变参数的前面这样函数才能先接受入参其他的丢给可变参数。 函数重载
function A()print(123)
end
A()function A(a)print(a)
end
A(1)输出
123
1在Lua中函数的重载十分简单只需在函数下方重写这个函数即可。在Unity中Lua能实现热更新例如修正一些Bug就是通过重载函数实现的举个例子 摘自Lua语言函数级别的重载
-- hotfix.lua
--- 执行热更新
-- oldmod是旧模块
-- newmod是新模块这个模块里只会提供要替换的函数相当于旧模块的一个子集。
function hotfix.run(oldmod, newmod)-- 收集旧模块的所有upvaluelocal uvmap collect_all_upvalue(oldmod)for k, v in pairs(newmod) doif type(v) function then-- 这里就是先把新函数的upvalue修正然后直接替换给旧模块oldmod[k] hotfix_func(v, uvmap)endend
end
return hotfix