《Lua程序设计》-- 学习10
环境(Environment)
具有动态名称的全局变量


全局变量的声明
由于Lua语言将全局变量存放在一个普通的表中,所以可以通过元表来发现访问不存在全局变量的情况。

正如前面所提到的,我们不允许值为nil的全局变量,因为值为nil的全局变量都会被自动地认为是未声明的。但是,要允许值为nil的全局变量也不难,只需要引入一个辅助表来保存已声明变量的名称即可。一旦调用了元方法,元方法就会检查该表,看变量是否是未声明过的。最终的代码可能与示例22.2中的代码类似。

现在,即使像x=nil这样的赋值也能够声明全局变量了。
非全局环境
在Lua语言中,全局变量并不一定非得是真正全局的。Lua语言竭尽全力地让程序员有全局变量存在的幻觉
一个自由名称(free name)是指没有关联到显式声明上的名称,即它不出现在对应局部变量的范围内。例如,在下面的代码段中,x和y是自由名称,而z则不是:

Lua语言把所有的代码段都当作匿名函数。所以,Lua语言编译器实际上将原来的代码段编译为如下形式:也就是说,Lua语言是在一个名为_ENV的预定义上值(一个外部的局部变量,upvalue)存在的情况下编译所有的代码段的。因此,所有的变量要么是绑定到了一个名称的局部变量,要么是_ENV中的一个字段,而_ENV本身是一个局部变量(一个上值)。

_ENV的初始值可以是任意的表(实际上也不用一定是表,我们会在后续讨论)。任何一个这样的表都被称为一个环境。为了维持全局变量存在的幻觉,Lua语言在内部维护了一个表来用作全局环境(global environment)。通常,当加载一个代码段时,函数load会使用预定义的上值来初始化全局环境。因此,原始的代码段等价于:

Lua语言中处理全局变量的方式:
•编译器在编译所有代码段前,在外层创建局部变量_ENV;
•编译器将所有自由名称var变换为_ENV.var;
•函数load(或函数loadfile)使用全局环境初始化代码段的第一个上值,即Lua语言内部维护的一个普通的表。
使用_ENV



环境和模块
函数load通常把被加载代码段的上值_ENV初始化为全局环境。不过,函数load还有一个可选的第四个参数来让我们为_ENV指定一个不同的初始值。

垃圾收集
弱引用表(weak table)、析构器(finalizer)和函数collectgarbage是在Lua语言中用来辅助垃圾收集器的主要机制。弱引用表允许收集Lua语言中还可以被程序访问的对象;析构器允许收集不在垃圾收集器直接控制下的外部对象;函数collectgarbage则允许我们控制垃圾收集器的步长。
弱引用表
简单地清除引用可能还不够。在有些情况下,还需要程序和垃圾收集器之间的协作。一个典型的例子是,当我们要保存某些类型(例如,文件)的活跃对象的列表时。这个需求看上去很简单,我们只需要把每个新对象插入数组即可;但是,一旦一个对象成为了数组的一部分,它就再也无法被回收了!虽然已经没有其他任何地方在引用它,但数组依然在引用它。除非我们告诉Lua语言数组对该对象的引用不应该阻碍对此对象的回收,否则Lua语言本身是无从知晓的。
弱引用表就是这样一种用来告知Lua语言一个引用不应阻止对一个对象回收的机制。所谓弱引用(weak reference)是一种不在垃圾收集器考虑范围内的对象引用。如果对一个对象的所有引用都是弱引用,那么垃圾收集器将会回收这个对象并删除这些弱引用。Lua用语言通过弱引用表实现弱引用,弱引用表就是元素均为弱引用的表,这意味着如果一个对象只被一个弱引用表持有,那么Lua语言最终会回收这个对象。
表由键值对组成,其两者都可以容纳任意类型的对象。在正常情况下,垃圾收集器不会回收一个在可访问的表中作为键或值的对象。也就是说,键和值都是强(strong)引用,它们会阻止对其所指向对象的回收。在一个弱引用表中,键和值都可以是弱引用的。这就意味着有三种类型的弱引用表,即具有弱引用键的表、具有弱引用值的表及同时具有弱引用键和值的表。不论是哪种类型的弱引用表,只要有一个键或值被回收了,那么对应的整个键值对都会被从表中删除。
一个表是否为弱引用表是由其元表中的__mode字段所决定的。当这个字段存在时,其值应为一个字符串:如果这个字符串是"k",那么这个表的键是弱引用的;如果这个字符串是"v",那么这个表的值是弱引用的;如果这个字符串是"kv",那么这个表的键和值都是弱引用的。

在本例中,第二句赋值key={}覆盖了指向第一个键的索引。调用collectgarbage强制垃圾收集器进行一次完整的垃圾收集。由于已经没有指向第一个键的其他引用,因此Lua语言会回收这个键并从表中删除对应的元素。然而,由于第二个键仍然被变量key所引用,因此Lua不会回收它。
请注意,只有对象可以从弱引用表中被移除,而像数字和布尔这样的“值”是不可回收的。例如,如果我们在表a(之前的示例)中插入一个数值类型的键,那么垃圾收集器永远不会回收它。当然,如果在一个值为弱引用的弱引用表中,一个数值类型键相关联的值被回收了,那么整个元素都会从这个弱引用表中被删除。
记忆函数(Memorize Function)
我们可以通过记忆(memorize)函数的执行结果,在后续使用相同参数再次调用该函数时直接返回之前记忆的结果,来加快函数的运行速度

对象属性(Object Attribute)
弱引用表的另外一种重要应用是将属性与对象关联起来。在各种各样的情况下,我们都需要把某些属性绑定到某个对象,例如函数名、表的默认值及数组的大小等。
瞬表
在Lua语言中,一个具有弱引用键和强引用值的表是一个瞬表。在一个瞬表中,一个键的可访问性控制着对应值的可访问性。更确切地说,考虑瞬表中的一个元素(k,v),指向的v的引用只有当存在某些指向k的其他外部引用存在时才是强引用,否则,即使v(直接或间接地)引用了k,垃圾收集器最终会收集k并把元素从表中移除。
析构器(Finalizer)
虽然垃圾收集器的目标是回收对象,但是它也可以帮助程序员来释放外部资源。出于这种目的,几种编程语言提供了析构器。析构器是一个与对象关联的函数,当该对象即将被回收时该函数会被调用。

相关文章:
《Lua程序设计》-- 学习10
环境(Environment) 具有动态名称的全局变量 全局变量的声明 由于Lua语言将全局变量存放在一个普通的表中,所以可以通过元表来发现访问不存在全局变量的情况。 正如前面所提到的,我们不允许值为nil的全局变量,因为值为…...
Linux内核编译-ARM
步骤一、下载源码及交叉编译器后解压 linux kernel官网 ARM GCC交叉编译器 步骤二、安装软件 sudo apt-get install ncurses-dev sudo apt-get install flex sudo apt-get install bison sudo apt install libgtk2.0-dev libglib2.0-dev libglade2-dev sudo apt install libs…...
开源编辑器:ONLYOFFICE文档又更新了!
办公软件 ONLYOFFICE文档最新版本 8.0 现已发布:PDF 表单、RTL、单变量求解、图表向导、插件界面设计等更新。 什么是 ONLYOFFICE 文档 ONLYOFFICE 文档是一套功能强大的文档编辑器,支持编辑处理文本文档、电子表格、演示文稿、可填写的表单、PDF&#…...
第3章 文件类型和目录结构
第3章 文件类型和目录结构 在这这章之前我们先学习一个前面使用过的命令 ls 查看文件ls 命令格式: [rootbogon redhat]# ls --helpUsage: ls [OPTION]... [FILE]...List information about the FILEs (the current directory by default).Sort entries alphabeti…...
前端构建变更:从 webpack 换 vite
现状 这里以一个 op (内部运营管理用)项目为例,从 webpack 构建改为 vite 构建,提高本地开发效率,顺便也加深对 webpack 、 vite 的了解。 vite 是前端构建工具,使用 一系列预配置进行rollup 打包&#x…...
记录基于Vue.js的移动端Tree树形组件
目录 一、Liquor Tree 入门 : Development Component Options 组件选项 Structure 结构 二、vue-treeselect Introduction 介绍 Getting Started 入门 Vue 树形选择器( Vue tree select )组件在搭建 Vue 的 app 中特别常用,Vue tree select 除了简单的树形结构…...
Vue中嵌入原生HTML页面的方法
在Vue中嵌入原生HTML页面通常可以通过组件或页面的方式来完成。下面将详细说明如何通过组件方式实现这个功能,并提供一个简单的代码示例。 方法说明 创建原生HTML页面:首先,你需要创建一个原生HTML页面,这个页面可以是一个独立的…...
17 # 类型检查机制:类型保护
例子: enum Type {Strong,Week }class Java {helloJava(){console.log(hello Java);} }class JavaScript {helloJavaScript(){console.log(hello JavaScript);} }function getLanguage(type: Type){let lang type Type.Strong ? new Java() : new JavaScript();…...
Vulnhub-RIPPER: 1渗透
文章目录 一、前言1、靶机ip配置2、渗透目标3、渗透概括 开始实战一、信息获取二、rips的使用三、获取密码文件四、日志审查五、提权 一、前言 由于在做靶机的时候,涉及到的渗透思路是非常的广泛,所以在写文章的时候都是挑重点来写,尽量的不饶…...
幻兽帕鲁自建服务器:可以使用香港服务器吗?
随着网络技术的发展,越来越多的游戏爱好者选择通过自建服务器来享受游戏的乐趣。幻兽帕鲁作为一款备受喜爱的游戏,也有不少玩家想要自建服务器进行游戏。而在选择服务器地点时,很多玩家会想到使用香港服务器。那么,是否可以使用香…...
Revisiting image pyramid structure for high resolution salient object detection
accv2022的技术,在我测评的数据集上确实要明显好于basnet,rembg等一众方法。 1.Introduction 使用LR数据集训练的方法通过调整输入尺寸可以在HR图像上产生不错的结果。本文主要关注仅使用LR数据集进行训练以产生高质量的HR预测。HR的有效感受野ERFs和LR…...
中移(苏州)软件技术有限公司面试问题与解答(7)—— kmalloc与vmalloc的区别与联系及使用场景
接前一篇文章:中移(苏州)软件技术有限公司面试问题与解答(0)—— 面试感悟与问题记录 本文参考以下文章: kmalloc与vmalloc如何选择 Vmalloc与kmalloc的区别 特此致谢! 本文对于中移…...
微服务-微服务Alibaba-Nacos 源码分析 (源码流程图)
客户端流程 客户端心跳与实例往服务端注册...
后端性能优化的一些总结
目录 1、背景 2、优化实现 2.1查询数据表速度慢 2.2调别人接口速度慢 2.3导入速度慢、 2.4导出速度慢的做出介绍 2.5统计功能速度慢 3、总结 1、背景 系统上线后,被用户反应系统很多功能响应时长很慢。用户页面影响速度有要求,下面针对查询数据表…...
【升级openssl1.1.1t报错libssl.so.1.1: cannot open shared object file】
升级openssl报错: openssl vesion openssl: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory 编译安装openssl1.1.1t当执行openssl version的时候,报上述错误,将编译到的…...
CVE-2024-0352 likeshop v2.5.7文件上传漏洞分析
本次的漏洞研究基于thinkPHP开发开的一款项目..... 漏洞描述 Likeshop是Likeshop开源的一个社交商务策略的完整解决方案,开源免费版基于thinkPHP开发。Likeshop 2.5.7.20210311及之前版本存在代码问题漏洞,该漏洞源于文件server/application/api/contr…...
JAVA处理类似饼状图占比和100%问题,采用最大余额法
前言: 在做数据统计报表的时候,有两种方式解决占比总和达不到100%或者超过100%问题。 第一种方式是前端echart图自带的算分框架。 第二种方式是java后端取处理这个问题。 现存问题: 前端不通过饼状图的方式去展示各个分类的占比累加和为100%问…...
MATLAB矩阵的操作(第一部分)
矩阵的基本知识 矩阵概念 矩阵(Matrix)在数学中是一个由复数或实数组成的矩形阵列,其元素按照行和列排列。矩阵的定义可以形式化地描述为: 一个 m 行 n 列的矩阵是一个有序的数表,其中包含 m*n 个数,可以…...
全面掌握Django的web框架Django Rest_Framework(一)
文章目录 Django Rest_Framework1. DRF介绍2.DRF特点3.环境安装与配置(1)DRF需要以下依赖(2)创建django项目 4.序列化器的使用(1)创建序列化器 5. 反序列化器使用 Django Rest_Framework 1. DRF介绍 Djan…...
AOP+Redisson 延时队列,实现缓存延时双删策略
一、缓存延时双删 关于缓存和数据库中的数据保持一致有很多种方案,但不管是单独在修改数据库之前,还是之后去删除缓存都会有一定的风险导致数据不一致。而延迟双删是一种相对简单并且收益比较高的实现最终一致性的方式,即在删除缓存之后&…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
