Lua基础(十七)环境

一    环境 Environment

(1) 默认_G有什么

    

lua语言将'全局环境自身'保存在'全局变量_G' --> _G._G <="等价"=> _G

备注:输出的结果来看有一个'_G',也'印证'了这一点

_G也是一张'普通(common)的表'

这个表'保存'了lua所有的'全局函数'和'全局变量'

 (2)lua5.1

1.  lua将'环境表'保存在一个'全局变量_G'中,可以对其'访问'和'设置'

备注:5.2之前还'没有_ENV'的概念,only有'_G'

2.  一般我们把需要'被访问'的'对象(变量)'和'函数'等放到这里,然后可以在'需要时'通过它来访问和使用

3.  可以通过value = _G["varname"]或者value = _G.varname来获得'动态'名字的全局变量

1)等价形式

 2)改变环境

lua5.1中的setfenv使用

lua5.1"允许"每个函数拥有一个'子集的环境'来查找"全局变量",可以通过'setfenv'来改变一个函数的环境

    语法:setenv(func or number,table),第一个参数可以是'数字'也可以是'函数'

    --1.  第'一'个参数若是"1"则表示当前函数,"2"则表示调用'当前函数'的函数 -->'依次类推'

    --2.  第'二'个参数是一个'新的环境'table

功能:setenv是在lua5.1中'改变函数作用域'的函数

强调:只有'设置了'setfenv了环境,getfenv才能'生效'

补充:'了解'即可

setfenv和getfen

 (3)lua5.2+

lua5.3 注册表 _G _ENV

5.2版本: '_G'是'_ENV中'的一个'key'

在5.2中: 操作a = 1"相当于"_ENV['a'] = 1

注意:5.2+没有'setfenv'

  

1)只有全局变量注册到_G

(4)应用

①  检测所有对全局表中不存在键的访问

解读: 所有'试图'对'不存在全局变量'的访问都将'引发'一个'error错误'

②    判断一个变量是否存在

二    非全局环境

要点: Lua语言'本质'上没有'全局变量',因此"_ENV"'不是'全局变量,而是一个upvalue'非局部变量'

①    概念

 ②    自有名称

概念: '没有关联'到显示声明上的名称,即它'不出现'在对应'局部变量'的范围内

简单理解:想对而言的'全局变量'

  

③    编译器处理机制

1.  lua语言把'所有的代码段'都当作'匿名函数'

  ④    _ENV

1.  _ENV的"初始值"可以是'任意的值',一般是'表table'

2.  任何一个'这样的表'被称之为'一个环境' -->"重点!!!"

3.  Lua语言在'内部维护'了一个表来用作'全局环境'

⑤    lua语言中处理全局变量规则

1.  前'两个规则'完全由编译器'预先定义'的

1)函数load

1.  load的'本质'就是在Lua代码中'运行'一段存储在'字符串中的代码'

2.  load有'另一层'含义,它是将字符串的内容作为一个'函数体返回'

当加载一个"代码段"时,函数会使用'预定义'的upvalue["上值"]来初始化环境

关注: _ENV变量的值的'由来'

细细体会: 有点'闭包'的味道

三    使用_ENV

说明: 主要是掌握从'上面三条规则'引申出来的一些'技巧'

_ENV'引用'的是其'所在位置'所有'可见'的_ENV变量

①    _ENV只是一个普通变量

1.  可以'赋值'

2.  可以'访问'
​
3.  改变'代码段'使用的环境  <-- "_ENV的用途"

备注:通过'覆盖_ENV变量'设置一个'全新的环境'

效果: 任何对'自由'名称"全局变量"的赋值都会引发'类似的错误'

  

②    显示使用_ENV绕过局部声明

  

③    案例

④    代码说明_G和_ENV的区别

+++++++++++++"三者结果一致"+++++++++++++

print(_ENV);    
print(_ENV._G); 
print(_G);      

原理解读 

⑤    案例

1)将当前环境变为空表

注意:如果'新环境'是空的,会'丢失'之前所有的"全局变量"

  

2)如何访问全局变量a

⑥    补充_G和_ENV的区别

注意: _ENV和_G的'调用' -->"_G"只是"_ENV"的一个键,只有在刚'初始化'的时候"_G==_ENV"

⑦    继承的方式使用环境 

⑧    _ENV关于函数

1)案例1

 2)案例2

局部'_ENV'

3)案例三

使用'私有环境'定义一个函数

每个'闭包'都会使用'自己的外部变量-->ENV(_upvalue)'来访问其'自由名称'

四    环境模块

了解即可: 个人倾向于'原始M.add'的方法

特点:模块的'主程序块'有一个'独占'的环境,该模块所有的函数'共享'这个环境

优点:在'调用'时,'不需要'任何'前缀'

 五     luajit

1.  lua 5.1和5.2是个'分水岭'

2.  luajit'只支持'5.1,介于luajit的'卓越性能'[快速、代码编译、ffi等],使用luajit的'不要去学'lua5.2

核心:openresty就是'基于'luajit,扩展了一些'新特性' --> openresty还得'参照'5.1

①②③④⑤⑥⑦⑧⑨⑩ 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值