11.模块与多脚本
11.1 知识点
全局变量和局部变量
全局变量
-- 直接 变量 = 值 声明的变量都是全局变量
a = 1
b = "123"
-- Lua 中的循环体内,如果也是 变量 = 值 这样赋值,也是全局变量
-- 循环体外也能使用
for i = 1, 2 do
c = "韬老狮" -- 循环体内全局变量赋值
end
print(c) -- 韬老狮,循环体外可以得到循环体内的全局变量赋值
项目里尽量少用全局变量;多脚本后易命名冲突、状态污染。
局部变量
-- 局部变量的关键字 local
-- 通过 local 变量 = 值 声明局部变量
for i = 1, 2 do
local d = "韬老狮"
print("循环中的d" .. d) -- 循环中的d韬老狮,循环体内可以使用局部变量
end
print(d) -- nil,循环体外不能使用局部变量
fun = function()
local tt = "123123123" -- 函数中加了 local,就是局部变量
end
fun()
print(tt) -- nil,函数中的 tt 加了 local,外部访问不到
local tt2 = "555"
print(tt2) -- 555,刚声明的局部变量当然可以使用
能写 local 尽量写 local,脚本多了全局变量会越来越乱。
执行多脚本
声明一个LuaMultiScriptTest.lua脚本
print("我是LuaMultiScriptTest脚本")
GlobalVariable = "我是全局变量"
print("在LuaMultiScriptTest脚本打印的:" .. GlobalVariable)
local LocalAVariable = "我是局部变量"
print("在LuaMultiScriptTest脚本打印的:" .. LocalAVariable)
-- 可以在脚本最后返回一个外部希望获取的内容
-- 比如返回一个局部变量,给外部得到
return LocalAVariable
多脚本执行关键字 require 用于执行并加载指定脚本
- 多脚本执行关键字
require,传入脚本名,用双引号或单引号包裹。 require后会执行并加载传入的脚本。- 写法:
require("脚本名")
require('脚本名')
- 注意:学习阶段脚本名尽量不要用中文。
- 执行的脚本要能被 Lua 的搜索路径找到。最简单的情况,就是和当前脚本在同一目录下。
require('LuaMultiScriptTest') -- 执行 LuaMultiScriptTest 这个测试 Lua 多脚本的脚本
-- 我是LuaMultiScriptTest脚本
-- 在LuaMultiScriptTest脚本打印的:我是全局变量
-- 在LuaMultiScriptTest脚本打印的:我是局部变量
print(GlobalVariable) -- 我是全局变量,LuaMultiScriptTest 脚本的全局变量能被当前脚本使用
print(LocalAVariable) -- nil,LuaMultiScriptTest 脚本的局部变量不能被当前脚本使用
-- 如果脚本已经被 require 加载执行过,再 require 一次不会重复执行
require("LuaMultiScriptTest")
-- require 执行一个脚本时,可以在脚本最后返回一个外部希望获取的内容
-- 比如返回一个局部变量,用一个变量来接
-- 由于 LuaMultiScriptTest 已经加载过一次,这里先卸载 LuaMultiScriptTest
package.loaded["LuaMultiScriptTest"] = nil
-- 再重新加载 LuaMultiScriptTest
local testLA = require("LuaMultiScriptTest")
-- 我是LuaMultiScriptTest脚本
-- 在LuaMultiScriptTest脚本打印的:我是全局变量
-- 在LuaMultiScriptTest脚本打印的:我是局部变量
print(testLA) -- 我是局部变量
require 会把结果缓存到 package.loaded;同一脚本再次 require 默认不重新执行,直接返回缓存。
package.path 简单理解
require按package.path搜索脚本;学习阶段可理解为当前目录 + 默认路径。- 项目里路径可能被框架或自定义 Loader 接管(如 Unity 热更,xLua和toLua)。
print(package.path)
package.path 里通常会有类似 ?.lua、?/init.lua 这样的规则。
这里的 ? 会被替换成模块名。比如:
require("LuaMultiScriptTest")
Lua 会根据 package.path 里的规则,尝试去找对应的 LuaMultiScriptTest.lua。
require 按 package.path 找 .lua。
卸载多脚本
package.loaded["脚本名"]里保存的是该脚本的加载结果。- 如果脚本没有显式
return,通常会缓存为true。 - 如果脚本最后
return了一个值,就会缓存这个返回值。 package.loaded["脚本名"] = nil可以把已经加载过的脚本从缓存里移除。- 移除之后,再次
require这个脚本时,就会重新加载执行。
print(package.loaded["LuaMultiScriptTest"]) -- 如果脚本最后 return 了局部变量,这里打印的就是返回值
-- package.loaded["脚本名"] = nil 卸载已经执行过的脚本
package.loaded["LuaMultiScriptTest"] = nil
print(package.loaded["LuaMultiScriptTest"]) -- nil
-- 可以重新加载 LuaMultiScriptTest 了
require("LuaMultiScriptTest")
-- 我是LuaMultiScriptTest脚本
-- 在LuaMultiScriptTest脚本打印的:我是全局变量
-- 在LuaMultiScriptTest脚本打印的:我是局部变量
注意热重载时不能只清 package.loaded,旧引用等问题后面再学习。
大G表
_G表是一个全局表,它保存了全局环境中的变量。- 直接声明的全局变量,会放到
_G里。 - 加了
local的局部变量,不会放到_G表中。
for k, v in pairs(_G) do
print(k, v)
-- a 1
-- string table: 00B49FE8
-- xpcall function: 00B479D0
-- b 123
-- package table: 00B48050
-- tostring function: 00B47950
-- print function: 00B47590
-- os table: 00B4A038
-- ...
end
-- 局部变量,加了 local 的变量,不会存到 _G 表中
少写全局变量,就是在减少 _G 污染。
11.2 知识点代码
Lesson11_模块与多脚本.lua
print("**********模块与多脚本************")
print("**********知识点一 全局变量和局部变量************")
-- 全局变量
-- 直接 变量 = 值 声明的变量都是全局变量
a = 1
b = "123"
-- Lua 中的循环体内,如果也是 变量 = 值 这样赋值,也是全局变量
-- 循环体外也能使用
for i = 1, 2 do
c = "韬老狮" -- 循环体内全局变量赋值
end
print(c) -- 韬老狮,循环体外可以得到循环体内的全局变量赋值
-- 全局变量不是不能用,但项目里一般不建议乱用
-- 脚本多了以后,全局变量很容易造成命名冲突和状态污染
-- 局部变量
-- 局部变量的关键字 local
-- 通过 local 变量 = 值 声明局部变量
for i = 1, 2 do
local d = "韬老狮"
print("循环中的d" .. d) -- 循环中的d韬老狮,循环体内可以使用局部变量
end
print(d) -- nil,循环体外不能使用局部变量
fun = function()
local tt = "123123123" -- 函数中加了 local,就是局部变量
end
fun()
print(tt) -- nil,函数中的 tt 加了 local,外部访问不到
local tt2 = "555"
print(tt2) -- 555,刚声明的局部变量当然可以使用
print("**********知识点二 执行多脚本************")
-- 多脚本执行关键字 require,传入脚本名,用双引号或单引号包裹
-- require 后会执行并加载传入的脚本
-- require("脚本名")
-- require('脚本名')
-- 注意:学习阶段脚本名尽量不要用中文
-- 执行的脚本要能被 Lua 的搜索路径找到,最简单的情况是和当前脚本在同一目录下
require('LuaMultiScriptTest') -- 执行 LuaMultiScriptTest 这个测试 Lua 多脚本的脚本
-- 我是LuaMultiScriptTest脚本
-- 在LuaMultiScriptTest脚本打印的:我是全局变量
-- 在LuaMultiScriptTest脚本打印的:我是局部变量
print(GlobalVariable) -- 我是全局变量,LuaMultiScriptTest 脚本的全局变量能被当前脚本使用
print(LocalAVariable) -- nil,LuaMultiScriptTest 脚本的局部变量不能被当前脚本使用
-- 如果脚本已经被 require 加载执行过,再 require 一次不会重复执行
require("LuaMultiScriptTest")
-- require 执行一个脚本时,可以在脚本最后返回一个外部希望获取的内容
-- 比如返回一个局部变量,用一个变量来接
-- 由于 LuaMultiScriptTest 已经加载过一次,这里先卸载 LuaMultiScriptTest
package.loaded["LuaMultiScriptTest"] = nil
-- 再重新加载 LuaMultiScriptTest
local testLA = require("LuaMultiScriptTest")
-- 我是LuaMultiScriptTest脚本
-- 在LuaMultiScriptTest脚本打印的:我是全局变量
-- 在LuaMultiScriptTest脚本打印的:我是局部变量
print(testLA) -- 我是局部变量
print("**********知识点三 package.path 简单理解************")
-- require 不是凭空找到脚本的
-- 它会按照 package.path 里的搜索路径去查找 当前目录 + Lua 默认搜索路径
-- 项目里 require 的加载路径可能会被框架或者自定义 Loader 接管
print(package.path)
-- package.path 里通常会有类似 ?.lua、?/init.lua 这样的规则
-- 这里的 ? 会被替换成模块名
-- 比如 require("LuaMultiScriptTest") 时
-- Lua 会根据 package.path 里的规则,尝试去找 LuaMultiScriptTest.lua
print("**********知识点四 卸载多脚本************")
-- package.loaded["脚本名"] 里保存的是该脚本的加载结果
-- 如果脚本没有显式 return,通常会缓存为 true
-- 如果脚本最后 return 了一个值,就会缓存这个返回值
print(package.loaded["LuaMultiScriptTest"]) -- 如果脚本最后 return 了局部变量,这里打印的就是返回值
-- package.loaded["脚本名"] = nil 可以把已经加载过的脚本从缓存里移除
package.loaded["LuaMultiScriptTest"] = nil
print(package.loaded["LuaMultiScriptTest"]) -- nil
-- 移除之后,再次 require 这个脚本时,就会重新加载执行
require("LuaMultiScriptTest")
-- 我是LuaMultiScriptTest脚本
-- 在LuaMultiScriptTest脚本打印的:我是全局变量
-- 在LuaMultiScriptTest脚本打印的:我是局部变量
print("**********知识点五 大G表************")
-- _G 表是一个全局表,它保存了全局环境中的变量
-- 直接声明的全局变量,会放到 _G 里
-- 加了 local 的局部变量,不会放到 _G 表中
for k, v in pairs(_G) do
print(k, v)
-- a 1
-- string table: 00B49FE8
-- xpcall function: 00B479D0
-- b 123
-- package table: 00B48050
-- tostring function: 00B47950
-- print function: 00B47590
-- os table: 00B4A038
-- ...
end
-- 局部变量,加了 local 的变量,不会存到 _G 表中
LuaMultiScriptTest.lua
print("我是LuaMultiScriptTest脚本")
GlobalVariable = "我是全局变量"
print("在LuaMultiScriptTest脚本打印的:" .. GlobalVariable)
local LocalAVariable = "我是局部变量"
print("在LuaMultiScriptTest脚本打印的:" .. LocalAVariable)
-- 可以在脚本最后返回一个外部希望获取的内容
-- 比如返回一个局部变量,给外部得到
return LocalAVariable
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com