Knit 函数签名在作为服务和模块之间的参数传递时发生变化

问题描述 投票:0回答:1

因此,通过一个事件,我使用我的 SCP867Service:Test 到我的效果模块

--Service script
function SCP867Service:Test(player)
    Effect.Apply(self.PrintSomething, player, 10, 1, "Test")
    wait(5)
    Effect.Remove(self.PrintSomething, player, "Test")
end
--Module script
function effect.Apply(func, player, duration, tickSpeed, tag)
    
    --Check if the player already has the effect, bad code we don't check nil cases
    local owningPlayer = game.Players:GetPlayerFromCharacter(player.Parent)
    if effectsStorage[owningPlayer] and not Macros.findValue(effectsStorage[owningPlayer], func) then
        --Adding to all tables
        local functionCoroutine = coroutine.create(function()func(player, duration, tickSpeed)end)

在调试中,这些值看起来是正确的,玩家是我传递的人形机器人,持续时间为 10,tickSpeed 为 1。然后执行原始服务脚本中的函数:

function SCP867Service:PrintSomething(player, duration, tickSpeed)
    for i = 1, duration, 1 do
        print("Testing count: ", i)
        task.wait(tickSpeed)
    end
end

但是这里玩家= 10,持续时间= 1并且tickSpeed = nil 是什么原因造成的?

我做了所有能做的调试,发现在模块脚本和协程中执行的函数之间的某个地方需要一个附加值。我添加了一个补丁工作解决方案,在我的播放器之前传递一个额外的 nil 以使我的代码正常工作,但这似乎不是正确的解决方案。

local functionCoroutine = coroutine.create(function() func(nil, player, duration, tickSpeed)end)
lua roblox
1个回答
0
投票

让我们沿着这个协程内的

func
的路径走:

coroutine.create(function()
    func(player, duration, tickSpeed)
end)

您将其作为

self.PrintSomething
传递到父函数中,但它在模块上定义为
<moduleName>:PrintSomething
。注意到句号和冒号之间的区别了吗?

当您使用冒号定义函数时,这是函数签名的语法糖,该函数签名将

self
对象作为隐藏的第一个参数传递。这意味着什么:

function module:PrintSomething(a, b, c) end
-- is the same as...
function module.PrintSomething(self, a, b, c) end

因此,因为您使用冒号定义了

PrintSomething
函数,所以预计您将使用冒号调用该函数,或者手动传入
self
对象。既然你没有,它会将你 did 传入的第一个参数视为
self
,这就是为什么你的所有输入都偏移了一个。

在这种情况下,你很幸运,因为你的

PrintSomething
函数不会在任何地方访问
self
,它不需要是成员函数,你可以将其设为静态函数。因此,只需将函数签名更改为句点函数即可:

function SCP867Service.PrintSomething(player, duration, tickSpeed)
© www.soinside.com 2019 - 2024. All rights reserved.