当我们在全局环境中定义变量时经常会有命名冲突,尤其是在使用一些库的时候,变量声明可能会发生覆盖,这时候就需要一个非全局的环境来解决这问题。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

设置函数环境——setfenv(转)的更多相关文章

  1. 设置函数环境——setfenv

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

  2. R语言环境变量的设置 环境设置函数为options()

    环境设置函数为options(),用options()命令可以设置一些环境变量,使用help(options)可以查看详细的参数信息. 1. 数字位数的设置,options(digits=n),n一般 ...

  3. QT小记之在VS2005中使用(设置QMAKESPEC环境变量,以及编译QT Lib)

    QT的结构很清晰明了,看过第一个HELLO WORLD便爱上了它,感觉CEGUI有借鉴过QT的设计.如何在Windows平台下使用QT开发?一,下载SDK包请去官网(QT被NOKIA收购,貌似使用协议 ...

  4. linux 的时区设置函数tzset() 【转】

    linux 的时区设置函数tzset() 本文转载于: http://blog.csdn.net/epicyong333/article/details/5258152 tzset #incude & ...

  5. windows上自动设置java环境变量的脚本

    近期打算学习安卓开发,于是乎要准备java开发环境,安装好jdk后,就要设置java环境变量,java环境变量要设置JAVA_HOME,Path,CLASSPATH三个值,每次配置查百度复制粘贴都很麻 ...

  6. mac下设置maven环境

    在mac系统下设置maven环境. 1.首先通过终端打开    .bash_profile 2.设置maven解压后的路径地址 环境变量设置如下: MAVEN_HOME .PATH 两个变量即可 3. ...

  7. nodejs设置NODE_ENV环境变量

    看下app.js文件中的一部分代码,如下: //开发环境错误处理 // will print stacktrace if (app.get('env') === 'development') { ap ...

  8. windows下如何设置mysql环境变量

    方法一: windows下如何设置mysql环境变量 关键词: mysql, Setting Environment Variables, 环境变量设置 我的电脑->属性->高级-> ...

  9. ubuntu12中设置PATH环境变量的几种方法(三种办法)

    如果在Ubuntu12系统中自行安装了一些软件,特别是使用tar.gz文件包安装的软件,通常会放在/usr/local或者/opt,甚至放在/home下,但是如果要调用或执行时,必须加上完整的路径才可 ...

随机推荐

  1. jquery ajax协调SpringMVCD实现局部刷新IV

    feedback.jsp: <%@ page language="java" import="java.util.*" pageEncoding=&quo ...

  2. 为什么php时间阅读RTF,p标签会出现红色

    为什么php读取富文本的时候,p标签会出现红线,怎么去掉,哪位大侠帮解决?跪求答案 就像以下一样,一遇到p标签就有红虚线 版权声明:本文博客原创文章,博客,未经同意,不得转载.

  3. mysql 服务启动报1607 error

    [问题说明] mysql曾经还是好好的,突然就不行了...不知道是否使用了腾讯C盘搬家工具引起的... watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2h ...

  4. 苹果iOS手机系统诊断功能是后门吗?

    7月20日,美国知名苹果iOS手机系统侦破专家扎德尔斯基在2014年世界黑客大会(HOPE/X)用幻灯片讲演揭露了苹果手机存在系统级"后门". 为此,7月23日.苹果公司马上做出回 ...

  5. PhantomJS是一个基于WebKit的服务器端JavaScript API

    PhantomJS是一个基于WebKit的服务器端JavaScript API,它基于 BSD开源协议发布.PhantomJS无需浏览器的支持即可实现对Web的支持,且原生支持各种Web标准,如DOM ...

  6. hdu5001(概率dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5001 题意:一个人随即从一个点出发,到达邻接点的概率相同,求出走d步都不会到达1~n点的每一点i的概率 ...

  7. C++ Primer中文版(第5版)

    <C++ Primer中文版(第5版)> 基本信息 作者: (美)Stanley B. Lippman(斯坦利 李普曼)    Josee Lajoie(约瑟 拉乔伊)    Barbar ...

  8. svn rm --keep-local ./QueryParser_kill.logs

    svn rm --keep-local ./QueryParser_kill.logs

  9. 从后台绑定数据到ligerui 的comboBox下拉框组件

    这次来记录一下ligerUI的comboBox下拉框组件,ligerUI的API里也有相关描写叙述,上面都是前台写死数据,然后显示在组件中,我这次要说的是将后台的数据绑定到下拉框组件中,废话不多说. ...

  10. KISSY 库 demo

    KISSY 是由淘宝前端project师们发起创建的一个开源 JS 类库. 它遵循的原则是 小巧灵活.简洁有用.愉悦编码.快乐开发. DEMO: <!DOCTYPE html> <h ...