全局变量(global variable)

在Lua中定义全局变量非常简单,就是定义变量的时候,前面不要加上local。
这个神秘的全局变量,其实本质上也是一个table,它把我们创建的全局变量都保存到一个table里。
这个table的名字是:_G。

gName = "globalVar"
print(gName)
print(_G.gName)
print(_G["gName"])
-- result:
--> globalVar
--> globalVar
--> globalVar

我们定义了一个全局变量gName,于是这个gName成为了_G的一个字段。

使用全局变量会有命名冲突和效率问题,因此我们在适用情况下往往使用局部变量。

局部变量(local variable)

局部变量只在被声明的哪个代码块内有效。
代码块:控制结构、函数、chunk(变量被声明的那个文件或者文本串)。

local fLocal = function(n)if (n == 1) thenreturn n;elsereturn n + fLocal(n-1)end
end
print("result:", fLocal(2))

会报错:attempt to call global ‘fLocal’ (a nil value)。
同样的道理,也是有两种修改方式:

  • 提前声明fLocal
    分析一下,函数fLocal中是不能识别自己的,那么编译器在到这里的时候还不能认识fLocal。这让我想起来某个语言的定义(具体是什么忘记了):只有匹配到”}”,才算定义完毕,编译器才会识别这个定义。那是什么意思呢?拿这里的local fLocal来说只有编译器解释到“end”的时候才表示fLocal定义完毕,才会有这个变量,不然都是非法的,所以解决办法就是把fLocal单独拿出来,这样编译器扫描一遍的时候就认识了,不会报错。

    local fLocal
    fLocal = function(n)if (n == 1) thenreturn n;elsereturn n + fLocal(n-1)end
    end
    print("result:", fLocal(2))
    

特例

Lua local function和function

  • 使用function声明的函数(全局函数)时,引用时不会因为声明的顺序找不到。
  • 使用local function声明的函数(局部函数)时,引用必须在函数声明后。
function test()test1()test2()
endfunction test1()print("test1")
endlocal function test2()print("test2")
endtest()

会报错:attempt to call global ‘test2’ (a nil value)
有两种修改方法:

  • 将local function test2的声明放到function test前面。
  • 将local function test2修改为function test2。

Lua local table和table

为什么local table比较特殊呢?首先,我们知道table的赋值与其他基本类型变量不同,是引用赋值

v1 = 1
v2 = v1 --创建了一个新的变量v2,v2的值与v1相同
v1 = nilt1 = { v=100}
t2 = t1 --只是为t1起了一个别名t2
t1.v = nil
print(v1,v2,t1.v,t2.v)

因此要注意:避免local表引用global表

a = 1
do
local a = a --创建了一个局部变量a,赋值为全局变量a的值1
a = 2
print(a)    --2
end
print(a)    --1
t = {}
t.a = 1
do
local t = t --这种写法是错误的,因为这里创建了一个局部表t,引用了全局表t,实际上是同一张全局表,失去了local的作用
t.a = 2
print(t.a)  --2
end
print(t.a)  --2

Note:

1.Lua 中的变量全是全局变量,无论语句块或是函数里,除非用 local 显式声明为局部变量,变量默认值均为nil。

2.使用local创建一个局部变量,与全局变量不同,局部变量只在被声明的那个代码块内有效。(代码块:指的是一个控制结构内,一个函数体,或者一个chunk(变量被声明的那个文件或者文本串))。

x = 10
local i = 1                 --local to the chunkwhile i <= x dolocal x = i * 2           --local to the while bodyprint(x)i = i + 1
endif i > 20 then local x                     -- local to the "then" bodyx = 20print(x + 2)
elseprint(x)
endprint(x)

运行结果:

2
4
6
8
10
12
14
18
20
10
10

注意:如果在交互模式下上面的例子可能不能输出如期结果,因为第二句的local i=1是一个完整的chunk,在交互模式下执行完这一句后,Lua 将开始一个新的chunk,这样第二句的i 已经超出他的有效范围。可将这段代码放在do…end中(相当于C的{…})。

3.尽可能使用局部变量,有两个好处:

  • 避免命名冲突。

  • 访问速度更快(原因是local变量是存放在lua的堆栈里面的是array操作,而全局变量是存放在_G中的table中,效率不及堆栈)。

Lua中的函数可以作为全局变量也可作为局部变量,当我们将函数保存在一个局部变量里时,我们将得到一个局部函数。局部函数和局部变量一样在一定范围内有效。

  • 使用function声明的函数为全局函数,在被引用时可以不会因为声明的顺序而找不到 。
  • 使用local function声明的函数为局部函数,在引用的时候必须要在声明的函数后面。
function test()test2()test1()
endlocal function test1()print("hello test1")
endfunction test2()print("hello test2")
endtest()

会报错:attempt to call global ‘test2’ (a nil value)
有两种修改方法:

  • 将local function test1的声明放到function test前面。
  • 将local function test1修改为function test1。

5.其他补充:

  • local变量过多也会有堆栈溢出的问题,一段过程下最多拥有200个local变量,且do end不算。类似这样:
local Class = {}local test1 = 1local test2 = 2... --to 199return Class

如果超过199,则会报出main function has more than 200 local variables的错误。当然这里说的是一段过程,所以函数是另算的,同样一个函数的过程最多也不能超过200个local变量(调用函数则算转入下一个过程了)。

  • 模块级local变量暂无限制,但是也要考虑到热更新方面的问题:若是选择使用模块级local变量去存储模块的数据,那么在热更新方面的处理将会变得十分麻烦。从这点考虑的话,模块级local变量最好只是用于引用别的模块为妙。

全局变量和局部变量(local variable)相关推荐

  1. Python 引用全局变量提示:local variable referenced before assignment. 问题解决办法,global使用方法介绍

    local variable 'a' referenced before assignment 就是说变量a在使用前没有被声明 可能的情况一般有两种: 情况一:变量没有被赋值直接引用了 def hel ...

  2. 零基础入门学习Python(18)-全局变量与局部变量

    函数与过程 函数(function)是有返回值的,即是干完事必须写报告的苦逼 过程(procedure)是简单的.特殊并且没有返回值的,即是完事后拍屁股一走了之的小混蛋 attention:Pytho ...

  3. python成员变量和全局变量_python 全局变量和局部变量详解笔记

    python,数据分析,有相关问题欢迎留言交流. 一.问题引入 在写爬虫进行批量命名时,比如说常用的解析网页时 url这个变量就是跨函数的.涉及到全局变量和局部变量的设置. 二.全局变量与局部变量的区 ...

  4. 【Python技巧】全局变量global和局部变量local

    全局变量就是放在函数外面的变量 函数内可以直接访问全局变量 函数内定义的变量是局部变量 同名的局部变量会覆盖全局变量 函数内修改全局变量需要用global 全局变量不是真的全局变量,只是在模块内全局变 ...

  5. Java | 局部变量(Local Variable)

    Java 局部变量 前言 概述 声明局部变量 修饰符 局部变量名 使用局部变量 前言 本文原创作者为 Blume,版权归原创作者所有. 本文主要内容根据 Java 官方教程中<课程:语言基础&g ...

  6. ieda-自动引入局部变量(introduce local variable)快捷键

    idea中 一个很好用的快捷键,自动创建对象类型和对象名. ctrl+alt+V 将自动创建一个对象和对象名,快捷键 ctrl+alt+V , introduce local variable 非常方 ...

  7. Linux shell 学习笔记(4)— linux 环境变量(全局变量、局部变量及变量持久化)

    1. 环境变量概念及分类 bash shell 用一个叫作环境变量(environment variable)的特性来存储有关 shell 会话和工作环境的信息(这也是它们被称作环境变量的原因).这项 ...

  8. python全局变量有缩进吗_Python全局变量和局部变量的问题 400 请求报错 -问答-阿里云开发者社区-阿里云...

    # coding:utf-8 sum = 5 def add(x, y): print sum sum = x + y if __name__ == '__main__': add(7, 8) 上面的 ...

  9. python 错误--UnboundLocalError: local variable '**' referenced before assignment

    1 val = 9 2 def test(flag): 3 if flag: 4 val = 1 5 else: 6 print("test") 7 return val 8 9 ...

最新文章

  1. 【新无人机数据集】从 行人重识别 到 无人机目标定位
  2. 上周热点回顾(10.27-11.2)
  3. 计算机主板上电源怎么插,教大家电脑主板上的电源开关插头怎么接
  4. 使用sklearn来处理类别数据
  5. 专访腾讯多媒体实验室商世东:咬咬牙也要跟上新版本的发布
  6. 电脑动态壁纸_每日壁纸—水彩插画少女动漫手机高清无水印壁纸第二波
  7. Kapacitor安装及使用
  8. UIControl UIImage
  9. C++中之---数组和vector
  10. 使用计时器setInterval实现倒计时
  11. EndNote X7集成到office word2016(原有EndNote选项卡,却突然消失)
  12. 冬夜读书示子聿 鉴赏
  13. SVG格式文件可以用什么软件打开?
  14. 今日分享-ios蓝牙
  15. 生命探测仪能穿墙能探废墟 但不能穿透金属(图)
  16. 对SG函数(Sprague-Garundy函数)及其应用的简单解释与证明
  17. codeforces 545 Round #303 (Div. 2) E Paths and Trees
  18. 不需要网络的调频收音机_五六十年代不需要电的收音机
  19. ICMP、IGMP、RARP、ARP以及Tcp/Ip等一些含义说明(软考必考)
  20. NOI2020D2T2超现实树题解

热门文章

  1. 2015湘潭邀请赛小记
  2. linux隐藏文件夹共享,实现samba隐藏无权限用户文件夹配置
  3. 全网独家3.1.2版本独立微信社群人脉系统社群空间站最新源码开源+详细教程
  4. 计算机的分区原理,详解磁盘分区的基本原理
  5. arcgis读取oracle数据库,arcgis连接Oracle数据库
  6. #创新应用#文件大师:小身躯大智慧!
  7. 用python绘制树和森林_使用Python的Turtle库绘制森林的实例
  8. 电脑上如何使用Excel提升工作效率?
  9. Javascript正则表达式(括号)、[中括号]、{大括号}的区别小结
  10. Node.JS中调用JShaman,加密JS代码