• chapter 14_1 环境


      Lua将其所有的全局变量保存在一个常规的table中,称为“global environment”。

    Lua将环境table自身保存在一个全局变量_G中,_G._G等于 _G .

    比如下面的代码打印出_G中所有的全局变量:

    for n in pairs(_G) do 
        print(n)
    end

    具有动态名字的全局变量

      对于访问和设置全局变量,通常赋值操作就可以了。不过,有时也会用到一些元编程的形式。

    当操作一个全局变量时,而它的名称却存储在另一个变量中,或者需要通过运行时的计算才能得到。

    为了获取这个变量的值,往往这样写:

    value = loadstring("return " .. varname)()

    如果varname是x,那么结果就是字符串"return x ".

    然而,这段代码中包含了一个新程序块的创建和编译。因此可以使用以下代码来完成相同的效果,但效率上要高出一个数量级:

    value = _G[varname]

    正因为环境是一个常规的table,才可以使用一个key去直接索引它。类似地,还可以动态计算一个名称,然后将一个值赋予该名称的全局变量:

    _G[varname] = value

    不过注意,有些程序员对于该技能的运用有些过度,可能写出

    _G["a"] = _G["var1"]

    其实就是简单一句 a = var1。

      上面的问题的一般化形式是,允许使用动态的字段名,如“io.read" 或 "a.b.c.d"。

    如果直接写_G["io.read"]则不会从table io 中得到字段read。但可以写一个函数getfield来实现这个效果。

    即通过调用getfield("io.read") 返回所要求的结果。这个函数是一个循环,从_G开始逐个字段地深入求值:

    function getfield(f)
        local v=_G        --从全局变量的table开始
        for w in string.gmatch(f,"[%w_]+") do
            v = v[w]
        end
        return v
    end

    依靠string库中的gmatch来遍历 f 中所有的单词。

    与之对应的设置字段的函数则稍显复杂。像a.b.c.d = v 这样的赋值等价于以下代码:

    local  temp = a.b.c
    temp.d = v

    也就是说,必须一直检索到最后一个名称,然后分别进行操作。下面这个函数setfield就完成了这项任务,并且创建路径中间那些不存在的table。

    function setfield(f,v)
        local t = _G                --从全局变量的table开始
        for w , d in string.gmatch ( f ,"([%w_]+) (%.?)" )  do
            if d == "." then        --是最后一个字段吗?
                t[w] = t[w] or {}   --如果不存在就创建table
                t = t[w]            --获取该table
            else
                t[w] = v
            end
        end
    end

    上例中用到了一种字符串模式,通过这种模式就可以将字段名捕获到变量w中,并将一个可选的句号捕获到d中。

    调用上面的这个函数:

    setfield("t.x.y",10)

    便创建了两个table:全局 t 和 t.x ,并将10赋值给t.x.y :

    print(t.x.y)             --> 10
    print(getfield("t.x.y"))    --> 10

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

  • 相关阅读:
    标准输入输出流
    打印流
    数据输入输出流
    对象操作流
    随机流
    内存输出流
    序列流
    转换流示例代码
    字符流的示例代码
    字符流
  • 原文地址:https://www.cnblogs.com/daiker/p/5853906.html
Copyright © 2020-2023  润新知