【Lua学习笔记】Lua进阶——函数和闭包

文章目录
- 函数
- 函数嵌套
- 闭包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
在上述闭包中,两个闭包f1,f2使用的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 i=1,#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
相关文章:
【Lua学习笔记】Lua进阶——函数和闭包
文章目录 函数函数嵌套闭包Closures可变函数函数重载 函数 函数嵌套 function A()print("这里是函数A")return function ()print("返回函数不要起名")end end B A() B()输出: 这里是函数A 返回函数不要起名使用函数嵌套的用法,我…...
大学生竞赛管理系统springboot比赛报名信息java jsp源代码mysql
本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 大学生竞赛管理系统springboot 系统有3权限ÿ…...
UnixBench 5.1.3 银河麒麟桌面操作系统V10 (SP1) ARM64 aarch64 图形性能测试 2d 3d, glmark2 3d测试
编译 安装libgl sudo apt install libgl-dev yeqiangyeqiang-greatwall:~/Downloads/UnixBench$ sudo apt install libgl-dev [sudo] yeqiang 的密码: 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 下列软件包…...
JavaScript高级——ES6基础入门
目录 前言let 和 const块级作用域模板字符串一.模板字符串是什么二.模板字符串的注意事项三. 模板字符串的应用 箭头函数一.箭头函数是什么二.普通函数与箭头函数的转换三.this指向1. 全局作用域中的 this 指向2. 一般函数(非箭头函数)中的this指向3.箭头…...
2023年超越期待的高性能视频剪辑主机推荐| Intel 蝰蛇峡谷测评
1、开箱 蝰蛇峡谷的开箱体验是非常令人兴奋的。首先,打开包装后,你会看到一个精致且高质感的机箱,给人一种专业的感觉。蝰蛇峡谷的外观设计简洁大方,黑色的机箱与红色的Logo相得益彰,展现了其高性能的特点。 在打开机…...
1400*A. Factory
Examples input 1 5 output No input 3 6 output Yes 题意: a 和 m,a 不断加 a%m ,如果 a 有一次能够被 m 整除,则打印 Yes,如果一直循环永远不可能被 m 整除,则打印 No 解析: 可以观…...
OpenHarmony开源鸿蒙学习入门 - 基于3.2Release 应用开发环境安装
OpenHarmony开源鸿蒙学习入门 - 基于3.2Release 应用开发环境安装 基于目前官方master主支,最新文档版本3.2Release,更新应用开发环境安装文档。 一、安装IDE: 1.IDE安装的系统要求 2.IDE下载官网链接(IDE下载链接) …...
Linux 查看服务器内存、CPU、网络等占用情况的命令
1、查看物理CPU个数:cat cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l 2、查看服务器CPU内核个数:cat 每个物理CPU中core的个数(即核数) cat /proc/cpuinfo | grep "cpu cores" | u…...
调用webservice导excel文件内容进入数据库
一个早期vb.net写的程序,需要增加功能,要导入excel数据,并按条件显示。 1.数据库端 1.1因为是要把表作为存储过程的输入参数,所以先新建一个数据类型xtabletype create type xtabletype as table(prodid varchar(20),itemid varchar(20),target varchar(150)) 1.2新建…...
*CTF 2023 web jwt2struts 题解wp
jwt2struts 根据题目名字猜测,这题考察jwt和Struts2 包里面果然有一个cookie 验证了,是jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiZXhwIjoyMDA2MjI1MjgxfQ.F7vOtdqg48M1DYK4tVZywTipIYDqKfsBSju7ekLSecU 我们的目标应该是把user改…...
使用java实时获取手环、手表的健康数据
吐槽 最近在自研开发一款有关读取健康数据的APP 但是数据来源非常稀少,申请了市面上所有的国内厂商的手环api都被拒了(因为是个人开发) 找了很久发现fitbit有开源的api于是淘了个fitbit的手表开始开发 Web API (fitbit.com) 在上述连接可…...
Maven右侧依赖Dependencies消失
项目右侧的Maven依赖Dependencies突然消失,项目中的注解都出现报错,出现这种情况应该是因为IDEA版本早于maven版本,重新检查项目中的Maven路径,选择File->Settings->搜索Maven,检查Maven home directory…...
100% RNN language model ChatRWKV 相关开源项目
RWKV(读作RwaKuv)借鉴了RNN的移动平均模型(MA),将transformer的 O ( T 2 d ) O(T^2d) O(T2d)复杂度降低到 O ( T d ) O(Td) O(Td),同时保持较好的结果表现。RWKV也是一个开源模型,甚至其介绍主页的html代码都有开源。以…...
ElasticSearch Window Linux部署
文章目录 一、Window 集群部署二、Linux 单节点部署三、Linux 集群部署 一、Window 集群部署 创建 elasticsearch-cluster 文件夹,在内部复制三个elasticsearch服务 修改集群文件目录中每个节点的 config/elasticsearch.yml 配置文件 # -----------------------…...
MyBatis-Plus 分页插件实现分页查询
目录 1. 配置分页查询的拦截器 2. 使用 Page 对象实现分页功能 1. 配置分页查询的拦截器 因为 MyBatis-Plus 里面使用了分页插件来实现分页查询, 所以我们需要将 MyBatis-Plus 的插件添加到当前的项目里, 这样我们执行的查询操作才会生效. 创建 PageConfig 类: Configurat…...
Nacos源码 (1) 源码编译及idea环境
本文介绍从gitee下载nacos源码,在本地编译,并导入idea进行本地调试。 从gitee下载源码 由于github访问速度慢,所以我选择使用gitee的镜像仓库: git clone https://gitee.com/mirrors/Nacos.git本文使用2.0.2版本,所…...
docker配置文件挂载(容器数据管理)
目录 数据卷(容器数据管理)什么是数据卷数据集操作命令创建和查看数据卷挂载数据卷案例案例-给nginx挂载数据卷案例-给MySQL挂载本地目录 总结 数据卷(容器数据管理) 在之前的nginx案例中,修改nginx的html页面时&#…...
uniAPP 视频图片预览组件
效果图 思路:处理文件列表,根据文件类型归类 已兼容 H5 ios 设备,测试已通过 浙政钉,微信小程序 视频资源因为,没有预览图,用灰色图层加播放按钮代替 <template><!--视频图片预览组件 -->&l…...
【论文阅读】The Deep Learning Compiler: A Comprehensive Survey
论文来源:Li M , Liu Y , Liu X ,et al.The Deep Learning Compiler: A Comprehensive Survey[J]. 2020.DOI:10.1109/TPDS.2020.3030548. 这是一篇关于深度学习编译器的综述类文章。 什么是深度学习编译器 深度学习(Deep Learning)编译器将…...
怎么维护自己的电脑?
方向一:我的电脑介绍 我使用的是一台来自知名品牌的笔记本电脑。它具有高性能的核心配置,如快速处理器、大容量内存和高性能显卡,以及宽敞的存储空间。我选择这台电脑主要是因为它的出色性能和可靠性,能够满足我在学习和工作中的…...
VSCode配置PyTorch开发环境:从CUDA版本检查到镜像源加速(附常见报错解决方案)
VSCode配置PyTorch开发环境:从CUDA版本检查到镜像源加速(附常见报错解决方案) 在深度学习领域,PyTorch凭借其动态计算图和易用性已成为研究者和开发者的首选框架。然而,配置PyTorch开发环境时,CUDA版本匹配…...
从理论到面包板:手把手搭建Series-Shunt反馈放大器(含阻抗匹配避坑指南)
从理论到面包板:手把手搭建Series-Shunt反馈放大器(含阻抗匹配避坑指南) 在电子工程实践中,反馈放大器设计是模拟电路领域的核心技能之一。Series-Shunt结构因其出色的电压放大特性和相对简单的实现方式,成为初学者入门…...
3大场景解放双手:SteamShutdown智能管理下载与自动控制电脑的完整方案
3大场景解放双手:SteamShutdown智能管理下载与自动控制电脑的完整方案 【免费下载链接】SteamShutdown Automatic shutdown after Steam download(s) has finished. 项目地址: https://gitcode.com/gh_mirrors/st/SteamShutdown 你是否曾在深夜开启游戏下载后…...
告别兼容性烦恼,让老旧应用在现代浏览器中“无缝”运行
在数字化转型的浪潮中,企业的技术架构往往承载着历史的痕迹。当我们享受着现代浏览器带来的极速体验与丰富扩展时,一个不容忽视的挑战正悄然影响着员工的工作效率与IT运维的平静——那就是“传统浏览器支持”问题。这并非一个遥不可及的技术概念…...
RDMA设计64:数据吞吐量性能测试分析
本博文主要交流设计思路,在本博客已给出相关博文约190篇,希望对初学者有用。 注意这里只是抛砖引玉,切莫认为参考这就可以完成商用IP 设计。 这里将在基于 XCZU47DR FPGA 核心的开发板上对 RoCE v2 高速传输系统进行数据吞吐量、包吞吐量及传…...
LongCat-Video:136亿参数开源AI视频生成模型的技术突破与实践指南
LongCat-Video:136亿参数开源AI视频生成模型的技术突破与实践指南 【免费下载链接】LongCat-Video 项目地址: https://ai.gitcode.com/hf_mirrors/meituan-longcat/LongCat-Video 在人工智能视频生成领域,长视频生成一直是技术挑战的制高点。传统…...
宇树机器狗Go2仿真入门:Gazebo环境下Gmapping建图全流程(附避坑指南)
宇树机器狗Go2仿真实战:Gazebo环境下的Gmapping建图与避坑指南 当四足机器人遇上SLAM技术,会碰撞出怎样的火花?宇树科技(Unitree)推出的Go2机器狗凭借其灵活的机动性和开源控制系统,已成为机器人开发者的热…...
利用快马AI快速原型化一个Python Socket聊天室应用
最近在学习计算机网络相关的知识,发现Socket编程是个很有意思的实践方向。正好在InsCode(快马)平台上尝试用AI快速原型化了一个Python Socket聊天室应用,整个过程比想象中顺利很多,分享下我的实现思路和体验。 项目背景与需求分析 这个聊天…...
Synopsys AXI VIP实战:如何用reorder和delay配置模拟真实SoC总线行为
Synopsys AXI VIP实战:用reorder与delay构建高保真SoC总线模拟环境 在SoC验证领域,AXI总线协议的复杂性常常成为验证工程师面临的主要挑战。当CPU通过Cache访问低速外设时,总线上的竞争、延迟和乱序响应会形成难以预测的行为模式。Synopsys A…...
保姆级教程:用Python复现MIT Cheetah的刚体模型与正运动学(附代码)
从零实现MIT Cheetah四足机器人刚体建模与运动学仿真 四足机器人一直是机器人领域的热门研究方向,而MIT Cheetah作为开源四足机器人中的佼佼者,其设计理念和算法实现值得每一位机器人爱好者深入研究。本文将带你从零开始,用Python完整实现MI…...
