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",)
便创建了两个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 》
chapter 14_1 环境的更多相关文章
- PHP微信商户支付 - 企业付款到零钱功能(即提现)技术资料汇总
PHP实现微信开发中提现功能(企业付款到用户零钱) 一.实现该功能目的 这几天在小程序里要实现用户从系统中提现到零钱的功能,查了一下文档可以使用 企业付款到用户零钱 来实现: 官方文档:https:/ ...
- MVC 微信扫码支付
微信扫码支付有两种模式, 模式一和模式二, 两者具体的区别可参考官网文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4 微 ...
- 微信红包店小程序开发过程中遇到的问题 php获取附近周边商家 显示最近商家
最近公司在做一个项目就是微信红包店.仿照的是微信官方在做的那个红包店的模式.客户抢红包,抢到以后到店消费,消费以后就可以拿到商家的红包了. 项目中的两个难点: 1通过小程序来发红包 这个之前在开发语 ...
- PHP实现微信开发中提现功能(企业付款到用户零钱)
一.实现该功能目的 这几天在小程序里要实现用户从系统中提现到零钱的功能,查了一下文档可以使用 企业付款到用户零钱 来实现: 官方文档:https://pay.weixin.qq.com/wiki/do ...
- PHP实现微信商户支付企业付款到零钱功能代码实例
本文为大家分享了PHP实现微信商户支付企业付款到零钱的具体代码,供大家参考,具体内容如下 微信支付开发文档 一.开通条件 企业付款为企业提供付款至用户零钱的能力,支持通过API接口付款,或通过微信支付 ...
- 小程序红包开发跳坑记 微信小程序红包接口开发过程中遇到的问题 微信小程序红包开发
现在做小程序的越来越多,商家推广也是一个瓶颈,谁不发点红包,都很难找到人来用你的微信小程序了.于是不管你开发什么小程序功能,你或多或少都要用到小程序来发红包吧. 我们自己之前做公众号发红包,做了两三 ...
- 微信小程序红包开发思路 微信红包小程序开发思路讲解
之前公司开发小程序红包,将自己在开发的过程中遇到的一些坑分享到了博客里.不少人看了以后,还是不明白怎么开发.也加了我微信咨询.所以今天,我就特意再写一篇文章,这次就不谈我开发中遇到的坑了.就主要给大家 ...
- Chapter 15_3 使用环境
创建模块的基本方法的缺点在于,忘记使用local,很容易就污染全局空间. “函数环境”是一种有趣的技术,它能够解决上面的问题.就是让模块的主程序块独占一个环境. 这样不仅它的所有函数可以共享这个tab ...
- Chapter 14_3 非全局的环境
关于“环境”的一大问题在于它是全局的,任何对它的修改都会影响程序的所有部分. 例如:若安装一个元表用于控制全局变量的访问,那么整个程序都必须遵循这个规范. 当使用某个库时,没有先声明就使用了全局变量, ...
随机推荐
- 工具-maya2014软件操作细节(持续更新……)
整体 ------------------------------------------------------- [全选控制器] 1.选中总控-显示-隔离选择-查看选定对象 2.全选并创建新层(不 ...
- MQTT协议之 Apache Apollo服务
一.说明 MQTT是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分.该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网) ...
- swift3 UIColor扩展
//返回一个RGB颜色 class func getColor(r:CGFloat,g:CGFloat,b:CGFloat,l:CGFloat = 1) ->UIColor{ let color ...
- 前端知识点-CSS相关知识点
1.解释一下CSS的盒子模型? 回答一: a.标准的css盒子模型:宽度=内容的宽度+边框的宽度+加上内边具的宽度 b.网页设计中常听的属性名:内容(content).填充(padding).边框(b ...
- 基于Java 的增量与完全备份小工具
前段时间,因为各种原因,自己动手写了一个小的备份工具,用了一个星期,想想把它的设计思路放上来,当是笔记吧. 需求场景:这个工具起初的目的是为了解决朋友公司对其网络的限制(不可以用任何同步软件,git, ...
- android 之 java环境部署
上甲骨文公司官网下载最新的jdk http://www.oracle.com/technetwork/cn/java/javase/downloads/jdk8-downloads-2133151-z ...
- 关于ios原声嵌入web页面的问题
当在一个界面中既有原生又有web的时候,如果想让上下整体滑动的话,我们怎么确定web的高度呢,下面分享一下我的心得 首先在webView的代理方法中我们可以获取到加载完整个web页面的高度 - (vo ...
- php 学习之对象
php中怎么实现创建一个对象然后全局都能调用? 在PHP中相当常见的一种情形时,我们只需要创建一个对象一次,然后在我们的整个程序中使用它.一个很好的例子就是smarty变量,一旦被初始化后就可以在任何 ...
- Linux Samba服务主配文件smb.conf中文详解
从网上找到描述比较详细的smb.conf中文解释: 服务名:smb 配置目录:/etc/sabma/ 主配置文件:/etc/sabma/smb.conf #====================== ...
- java JDBC测试
下载mysql-connector-java-5.1.31.jar添加到工程buildpath中 package com.jdbc.test; import java.sql.DriverManage ...