我是靠谱客的博主 欢喜大树,最近开发中收集的这篇文章主要介绍Lua中的require与package.loaded,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

require (modname)

加载一个模块。 这个函数首先查找 package.loaded 表, 检测 modname 是否被加载过。 如果被加载过,require 返回 package.loaded[modname] 中保存的值。 否则,它试着为模块寻找 加载器 。
require 遵循 package.searchers 序列的指引来查找加载器。 如果改变这个序列,我们可以改变 require 如何查找一个模块。 下列说明基于 package.searchers 的默认配置。
首先 require 查找 package.preload[modname] 。 如果这里有一个值,这个值(必须是一个函数)就是那个加载器。 否则 require 使用 Lua 加载器去查找 package.path 的路径。 如果查找失败,接着使用 C 加载器去查找 package.cpath 的路径。 如果都失败了,再尝试 一体化 加载器 (参见 package.searchers)。
每次找到一个加载器,require 都用两个参数调用加载器: modname 和一个在获取加载器过程中得到的参数。 (如果通过查找文件得到的加载器,这个额外参数是文件名。) 如果加载器返回非空值, require 将这个值赋给 package.loaded[modname]。 如果加载器没能返回一个非空值用于赋给 package.loaded[modname], require 会在那里设入 true 。 无论是什么情况,require 都会返回 package.loaded[modname] 的最终值。
如果在加载或运行模块时有错误, 或是无法为模块找到加载器, require 都会抛出错误。

package.loaded

用于 require 控制哪些模块已经被加载的表。 当你请求一个 modname 模块,且 package.loaded[modname] 不为假时, require 简单返回储存在内的值。
这个变量仅仅是对真正那张表的引用; 改变这个值并不会改变 require 使用的表。

简而言之就是:
在Lua中使用require进行模块的加载,被成功加载的模块会将这个模块的引用保存到package.loaded表中;在使用require进行模块加载的时候,会首先在package.loaded表中查找,检测这个模块是否被加载过,如果被加载过则返回这个模块在package.loaded中保存的值,否则加载这个模块!

那么问题来了,如果现在我需要重新加载一个已被成功加载过的模块呢?

例如:在进行更新之前就已经require过某一个模块,恰好本次的更新内容中就包含了这个模块的更新,在更新完成之后这个模块的内容发生了改变,但是由于在更新之前就已经require过了,package.loaded表中保存的这个模块的引用还是旧的,重新require无效!

其实解决办法很简单:在重新require之前将这个模块在package.loaded中保存的引用置空即可!

Test Demo
testRequire.lua

local testRequire = {name = "fightsyj"}

function testRequire:getName()
	return self.name
end

function testRequire:setName(name)
	self.name = name
end

return testRequire

test.lua

local modname = "testRequire"
local testRequire = require(modname)
print("------------------------------")
print(testRequire:getName())

delayDoSomething(function()
	testRequire = require(modname)  -- 在文件动态改变之后,重新require返回的依旧是原来就文件内容的引用
	print("------------------------------")
	print(testRequire:getName())

	package.loaded[modname] = nil  -- 将package.loaded表中保存的目标引用置空
	testRequire = require(modname)  -- 重新require这个模块
	print("------------------------------")
	print(testRequire:getName())
end, 5)  -- 延时5s,在这5s之内将testRequire.lua中的{name = "fightsyj"}改为{name = "fightsyj2"}

--[[ 
------------------------------
fightsyj
------------------------------
fightsyj
------------------------------
fightsyj2
]]

ps
delayDoSomething

参考:
Lua 5.3 参考手册

最后

以上就是欢喜大树为你收集整理的Lua中的require与package.loaded的全部内容,希望文章能够帮你解决Lua中的require与package.loaded所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部