在变量赋值时,函数的返回值会发生变化
我一直在折腾LÖVE2D框架,用于一个项目。在设计场景管理器的时候,遇到了这个问题,我找不到相关信息,也无法排查。
我有一个给定的场景,其包含一个 assets 字段,基本上是一个包含资源ID、类型(图片/字体等)以及用于用LÖVE的类型加载/初始化它的参数的表:
myScene.assets =
{
["my-logo-light"] = {"image", "path-to/my-light-asset/image.png"},
["my-logo-dark"] = {"image", "path-to/my-dark-asset/image.png"},
["colors-light"] = {"colors", 0, 151, 178},
["colors-dark"] = {"colors", 0, 0, 0}
}
然后,在 myScene 的父类,也就是 Scene 上,我有以下函数,用来确定资源应该如何加载并对其进行加载(忽略那些print语句,它们是用于调试的):
-- Load the scene's assets based on their type
function Scene:loadAssets()
for assetID, assetSpecs in pairs(self.assets) do
local assetTypeIndex, loadArgumentsIndex = 1, 2
local assetLoadFunction = self:getAssetLoadByType(assetSpecs[assetTypeIndex])
print("Pure function return value: ", assetLoadFunction(unpack(assetSpecs, loadArgumentsIndex)))
self.assets[assetID] = assetLoadFunction(unpack(assetSpecs, loadArgumentsIndex))
print("Function return value when assigned to variable: ", self.assets[assetID], "\n")
end
end
-- Determine the functions to load assets based on their type
function Scene:getAssetLoadByType(assetType)
local loadingFunction = {}
if assetType == "image" then
loadingFunction = love.graphics.newImage
elseif assetType == "font" then
loadingFunction = love.graphics.newFont
elseif assetType == "colors" then
loadingFunction = love.math.colorFromBytes
end
return loadingFunction
end
正如你所看到的,Scene:loadAssets() 会获取 Scene 实例的 assets 表并对其进行遍历,把资源类型传给 Scene:getAssetLoadByType() 以确定应使用哪一个函数来加载给定的资源。
接着,它调用合适的函数来加载资源,将 assetSpecs 表解包(其中包含资源的路径以及加载它所需的所有信息)以作为加载函数的参数使用。
问题在于,当我调用 myScene:loadAssets() 时,输出结果(为了清晰起见带有调试的打印语句)是:
Pure function return value: Image: 0x564c36cf4c00
Function return value when assigned to variable: Image: 0x564c36d3d4f0
Pure function return value: 0 0 0 nil
Function return value when assigned to variable: 0
Pure function return value: Image: 0x564c36cb30f0
Function return value when assigned to variable: Image: 0x564c36cb4110
Pure function return value: 0 0.5921568627451 0.69803921568627 nil
Function return value when assigned to variable: 0
从输出中可以看出,当我在调试时用print调用加载函数,如下所示:
print("Pure function return value: ", assetLoadFunction(unpack(assetSpecs, loadArgumentsIndex)))
所有资源都被正确加载,甚至包括从 love.math.colorFromBytes 返回的那些(参见;忽略 nil,我不是使用rgba而是rgb):
Pure function return value: Image: 0x564c36cf4c00
Pure function return value: Image: 0x564c36cb30f0
Pure function return value: 0 0 0 nil -- Black
Pure function return value: 0 0.5921568627451 0.69803921568627 nil -- Blue
但当这些值被赋给场景的 assets 字段并通过 print 进行检查时:
self.assets[assetID] = assetLoadFunction(unpack(assetSpecs, loadArgumentsIndex))
print("Function return value when assigned to variable: ", self.assets[assetID], "\n")
图像资源被正确分配:
Function return value when assigned to variable: Image: 0x564c36d3d4f0
Function return value when assigned to variable: Image: 0x564c36cb4110
但颜色资源却不对!它们都变成0:
Function return value when assigned to variable: 0
Function return value when assigned to variable: 0
(当然,我知道其实输出的是变量的赋值,而不是函数的返回值,但无论如何)
有人知道为什么会这样吗?
我似乎在我的代码中找不到错误(虽然我当然确信是我这边的问题,显然,我对LÖVE不太熟悉)。
感谢阅读。
解决方案
love.math.colorFromBytes 有4 个返回值。如果把结果用作函数的最后一个参数,就像你在“Pure”打印中那样,它会被视为一个可变参数并把它们全部作为独立的参数传递。但当赋给一个变量时,它只会取第一个返回值。例如
r = love.math.colorFromBytes(0, 151, 178)
print(r)
将简单地打印0,因为 r 只包含第一个返回值。你可以这样做
r, g, b, a = love.math.colorFromBytes(0, 151, 178)
把返回值分配给4 个不同的变量,然后得到
print(r) -- 0
print(g) -- 0.5921568627451
print(b) -- 0.69803921568627
print(a) -- nil