当我们在全局环境中定义变量时经常会有命名冲突,尤其是在使用一些库的时候,变量声明可能会发生覆盖,这时候就需要一个非全局的环境来解决这问题。setfenv函数可以满足我们的需求。

  setfenv(f, table):设置一个函数的环境

  (1)当第一个参数为一个函数时,表示设置该函数的环境

  (2)当第一个参数为一个数字时,为1代表当前函数,2代表调用自己的函数,3代表调用自己的函数的函数,以此类推

  所谓函数的环境,其实一个环境就是一个表,该函数被限定为只能访问该表中的域,或在函数体内自己定义的变量。下面这个例子,设定当前函数的环境为一个空表,那么在设定执行以后,来自全局的print函数将不可见,所以调用会失败。

-- 一个环境就是一个表,该表记录了新环境能够访问的全部域
newfenv = {}
setfenv(1, newfenv)
print(1) -- attempt to call global `print' (a nil value)

  我们可以这样继承已有的域:

a = 10
newfenv = {_G = _G}
setfenv(1, newfenv)
_G.print(1) -- 1
_G.print(_G.a) -- 10
_G.print(a) -- nil 注意此处是nil,新环境没有a域,但可以通过_G.a访问_G的a域

  可以看到,新环境中可以访问_G,但有一点就是_G中的所有函数必须手动调用,这样其实很不方便。我们可以使用metatable来对上述代码进行改进:

-- 任何赋值操作都对新表进行,不用担心误操作修改了全局变量表。另外,你仍然可以通过_G修改全局变量:
newfenv = {}
setmetatable(newfenv, {__index = _G})
setfenv(1, newfenv)
print(1) -- 1 新环境直接继承了全局环境的所有域,好处:可以不需要通过_G来手动调用

  这样,当访问到函数中不存在的变量时,会自动在_G中查找。对于当前函数和_G都存在的变量,可以通过是否用_G显示调用来区分,比如如果有两个a,那么_G.a表示继承来的,a就是当前函数环境的。

  另外,可以通过getfenv(f)函数查看函数所处的环境,默认会返回全局环境_G。

http://www.cnblogs.com/sifenkesi/p/3843348.html

最新文章

  1. 常用[js,css,jquery,html]
  2. CentOS7 搭建python3 Django环境
  3. C#窗体技巧
  4. (转)rlwrap真是一个好东西
  5. JavaWeb前端基础复习笔记系列 二
  6. JavaScript 面向对象程序设计(下)——继承与多态 【转】
  7. iOS 通过二进制判断图片类型
  8. Svn-在eclipse中安装svn插件
  9. 计算2的N次方
  10. iis7设置404页面不生效的原因
  11. 修改MySQL数据库的密码
  12. HDU 4714 Tree2cycle DP 2013杭电热身赛 1009
  13. vs在线工具杂烩
  14. 转:alphaImageLoader滤镜加载后 链接不能点击
  15. 深入理解计算机系统chapter7
  16. Spring MVC如何测试Controller(使用springmvc mock测试)
  17. java基础之接口(抽象类与接口的区别)
  18. Netty源码—三、select
  19. day2 and day3 总结-python基础-坚持就是胜利
  20. java matlab 混合编程 Failed to find the required library mclmcrrt9_2.dll on java.library.path.

热门文章

  1. java常见的输入和输出流案例研究(一个)
  2. Codeforces Round #248 (Div. 1)——Ryouko's Memory Note
  3. NYOJ115 市叛乱 【SPFA】
  4. 【PLSQL】绑定变量,活跃SQL,软硬解析解析
  5. Windows下文件或文件夹不能删除时的解决办法
  6. poj3126解题报告
  7. poj 3172 Scales 搜索
  8. hdu 1698 Just a Hook(线段树之 成段更新)
  9. 《JavaScript设计模式与开发实践》读书笔记之模板方法模式
  10. pygame系列_draw游戏画图