zoukankan      html  css  js  c++  java
  • Chapter 15_3 使用环境

      创建模块的基本方法的缺点在于,忘记使用local,很容易就污染全局空间。

    “函数环境”是一种有趣的技术,它能够解决上面的问题。就是让模块的主程序块独占一个环境。

    这样不仅它的所有函数可以共享这个table,而且它的所有全局变量也都记录在这个table中。还可以将所有的公有函数声明为全局变量。

    这样它们就自动地记录在一个独立的table中了。模块所要做的就是将这个table赋予模块名和package.loaded:

    local M = {}
    _ENV = M
    function add (c1,c2)
        return new(c1,r + c2.r, c1.i + c2.i)
    end

    当我们声明add函数后,它自动就到M.add中去了。在该模块中调用其它函数时,也不再需要前缀,new就会去找M.new。

    这样在调用一个导出的函数与一个私有函数就没有任何区别可言。就算忘记写local也不会污染全局命名空间,只会将一个私有函数变成了公有而已。

    但是问题来了:我们改变了_ENV环境变量,导致我们无法访问之前的全局变量。

    这里有几种方法可以解决(褒贬不一):

    1》继承

    local M = {}
    setmetatable(M,{__index = _G})
    _ENV = M

    现在module可以直接访问全局标识符,每次访问只需要付出很小的开销。这种方法导致了一个后果,从概念上说,此时的模块中包含了所有的全局变量。

    例如,通过该模块调用正弦函数:

    complex.math.sin(x)

    感觉像有点越界,不受控制了。

    2》用局部变量保存旧环境

    local M = {}
    local _G = _G
    _ENV = M        -- or _ENV = nil

    此方法必须在所有全局变量的名称前加上"_G",由于没有涉及到元方法,这种访问会比前面的方法快些。

    3》只加载需要的模块或函数(以local变量的方式)

    --模块设置
    local M = {}
    
    -- Import section: 导入段
    -- declare everything this module needs from outside
    -- 声明这个模块需要从外部引入的所有东西
    local sqrt = math.sqrt
    local io = io
    -- no more external access after this point
    --之后就不再需要外部的访问了
    _ENV = nil    -- or _ENV = M

    这种方法比较正规,但是这种技术要求做更多的工作,但是它能清晰地说明模块的依赖性。

    同时,比之前俩个方法运行的速度更快,应为它使用了local 变量。

    以上内容来自:《Lua程序设计第二版》和《Programming in Lua  third edition 》

  • 相关阅读:
    DNS解析原理图
    Linux 用户管理
    linux 磁盘基础知识学习
    python中readline判断文件读取结束的方法
    PLSQL Developer连接远程Oracle
    在Linux环境下的卸载Oracle11G操作
    MySQL INSERT插入条件判断:如果不存在则插入
    LoadRunner---杂问题&接口测试
    LoadRunner--获取请求的返回结果函数
    LoadRunner监控Linux条件和解决方法
  • 原文地址:https://www.cnblogs.com/daiker/p/5866022.html
Copyright © 2011-2022 走看看