《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 延时队列,实现缓存延时双删策略
一、缓存延时双删 关于缓存和数据库中的数据保持一致有很多种方案,但不管是单独在修改数据库之前,还是之后去删除缓存都会有一定的风险导致数据不一致。而延迟双删是一种相对简单并且收益比较高的实现最终一致性的方式,即在删除缓存之后&…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...
ThreadLocal 源码
ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物,因为每个访问一个线程局部变量的线程(通过其 get 或 set 方法)都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段,这些类希望将…...
用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法
用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法 大家好,我是Echo_Wish。最近刷短视频、看直播,有没有发现,越来越多的应用都开始“懂你”了——它们能感知你的情绪,推荐更合适的内容,甚至帮客服识别用户情绪,提升服务体验。这背后,神经网络在悄悄发力,撑起…...
