《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)

虽然垃圾收集器的目标是回收对象,但是它也可以帮助程序员来释放外部资源。出于这种目的,几种编程语言提供了析构器。析构器是一个与对象关联的函数,当该对象即将被回收时该函数会被调用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/663347.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java程序设计】【C00196】基于(JavaWeb+SSM)的旅游管理系统(论文+PPT)

基于(JavaWebSSM)的旅游管理系统(论文PPT) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于ssm的旅游平台 本系统分为前台、管理员2个功能模块。 前台:当游客打开系统的网址后,首先看到的…

C# 引用同一个dll不同版本的程序集

因为项目需要所以必须在项目中引用不同版本的同一程序集 我要引用的文件是newtonsoft.json.dll 两个版本为12.0.0.0 和4.0.0.0 1.如果已经先引入了newtonsoft.json 12.0.0.0版本的程序集,如果直接引入另一个版本的程序集的话会提示不成功,所以先将另一个…

分布式ID介绍实现方案总结

分布式 ID 介绍 什么是 ID? 日常开发中,我们需要对系统中的各种数据使用 ID 唯一表示,比如用户 ID 对应且仅对应一个人,商品 ID 对应且仅对应一件商品,订单 ID 对应且仅对应一个订单。 我们现实生活中也有各种 ID&…

BetrFS: A Compleat File System for Commodity SSDs——论文阅读

EuroSys 2022 Paper 分布式元数据论文汇总 问题 在不同的工作负载下,没有单一的Linux文件系统在普通SSD上始终表现良好。我们将一个完备的文件系统定义为在各种微基准测试和应用程序中,没有一个工作负载的性能低于最佳文件系统性能的30%,并…

EasyX图形库学习(一)

目录 一、easyX图形库基本介绍 1、easyX的原理 2、easyX的安装 3、easyX的颜色(RGB颜色模型) 颜色模型相关函数: 4、easyX的坐标 二、相关函数介绍: 绘图设备相关函数: 图形颜色及样式设置相关函数: 图形绘制相关函数: 文字输出相关…

Linux多线程服务端编程:使用muduo C++网络库 学习笔记 第十一章 反思C++面向对象与虚函数(下)

11.7.2 值语义与生命期 值语义的一个巨大好处是生命期管理很简单,就跟int一样——你不需要操心int的生命期。值语义的对象要么是stack object,要么直接作为其他object的成员,因此我们不用担心它的生命期(一个函数使用自己stack上…

分享个前端工具-取色调色工具

这里虽然贴了两个,但推荐 Pipette. PipetteWin22.10.22.zip: https://download.csdn.net/download/rainyspring4540/88799632 图标: 界面: ColorPix https://download.csdn.net/download/rainyspring4540/88799642 图标: 界面…

Google Play上架:因行为透明度被拒审或下架的政策自查(基于区块链的内容)

近期很多朋友的项目出现因行为透明度问题被谷歌拒审或者已经上架的包被下架甚至封号,今天解释一下为什么会被封号下架,根据是什么? 目录 政策发布时间与截止时间政策内容政策背景政策解析和问题讲解政策发布时间与截止时间 基于区块链的内容相关政策,于2023-07-12 公布,…

看完这篇文章,你一定能看懂Datasheet!

大家好,我是砖一。 针对以上学妹的疑问,我有几点建议,大家可以听一下~ 一,怎么样查找Datasheet(数据手册) 大多数人下意识就点开浏览器,把型号往里面一输,不建议这样。 对于刚入行…

Fluent的小bug处理:后处理截面显示存在漏洞

最近发现的Fluent的bug,关于后处理截面显示不完整的问题。 1 现象 在使用六面体核心类型单元(包括四面体-六面体核心和多面体-六面体核心)进行网格划分的时候,可能会在截面上不能完整捕捉单元形状及其分布状态,导致做…

linux使用iptables禁用ip

iptables是什么? iptables 是一个强大的开源软件,它是 Linux 系统内核中 netfilter 包过滤框架的一部分,用来实现防火墙功能。iptables 提供了一种灵活的方式来控制和管理进出以及通过 Linux 计算机的网络流量。 前提 我在云服务器上用doc…

【代码随想录】LC 1. 两数之和

文章目录 前言一、题目1、原题链接2、题目描述 二、解题报告1、思路分析2、时间复杂度3、代码详解 前言 本专栏文章为《代码随想录》书籍的刷题题解以及读书笔记,如有侵权,立即删除。 一、题目 1、原题链接 1. 两数之和 2、题目描述 二、解题报告 1、思…

2024美赛E题保姆级分析完整思路代码数据教学

2024美国大学生数学建模竞赛E题保姆级分析完整思路代码数据教学 E题:Sustainability of Property Insurance(财产保险的可持续性) 这道题目同样是比赛的热门题目,是很多同学在训练的时候经常做的题目类型了,属于大数据…

Spring事务:保障钱不会丢

在MySQL中简单的了解过事务,简单说事务就是把一组操作封装成一个执行单元,要么全部成功,要么全部失败。 在一次转账中,第一步A减去一百元,第二步B增加一百元。如果没有事务,第一步执行成功了,但…

Unity点乘和叉乘

目录 前言 点乘 一、点乘是什么? 二、应用 三、使用步骤 1.代码示例 叉乘 一、叉乘是什么? 二、应用 三、使用步骤 1.代码示例 总结 前言 Unity中经常会用到向量的运算来计算目标的方位,朝向,角度等相关数据&#xff0…

Springboot-前后端分离——第三篇(三层架构与控制反转(IOC)-依赖注入(DI)的学习)

本篇主要对ControllerServiceDAO三层结构以及控制反转(IOC)与DI(依赖注入)进行总结。 目录 一、三层架构: Controller/Service/DAO简介: 二、控制反转(IOC)-依赖注入(DI): 概念介绍: DOC与…

k8s安装dashboard报错CrashLoopBackOff

报错信息 使用kubectl get pods -A查看集群,出现错误: kubernetes-dashboard kubernetes-dashboard-xxxxxxxxxx6-2qrst 0/1 CrashLoopBackOff 6 15m查看日志后,发现原因: panic: Get "https://10…

【Django-ninja】分页管理器

django ninja通过paginate装饰器即可进行分页。内置了两个分页管理器LimitOffsetPagination和PageNumberPagination,能够实现基本的分页要求。当内置分页器不满足要求时,可以继承PaginationBase进行扩展自己的分页管理器。 1 使用分页器 from ninja.pa…

css3 属性 backface-visibility 的实践应用

backface-visibility 是一个用于控制元素在面对屏幕不同方向时的可见性的CSS3特性。它有两个可能的值: visible:当元素不面向屏幕(即背面朝向用户)时,元素的内容是可以被看到的。hidden:当元素不面向屏幕…

使用融合CDN同时提升网站效能及安全性

现在许多企业的服务都依靠网站营运,维持稳定的网站效能及安全性变得相当重要。事实上,当网站载入时间超过 3 秒钟,超过 40% 的使用者会直接跳出,由此可见网站效能的重要性;而当网站受到 DDoS 攻击时,处理起…