如何在Lua中将Object/table的函数保存到要从该变量调用的变量中?

How to save a function of an Object/table to a variable to be called from this variable in Lua?

提问人:skrovno_CZ 提问时间:11/7/2023 更新时间:11/7/2023 访问量:37

问:

我正在尝试使用 Lua OOP(面向对象编程),但我遇到了一些问题。

下面是一个带有注释的示例代码:

Object = {string = "Default"}

function Object:new()
    local o = {}
    setmetatable(o, {__index = self})
    -- o.string = "Default"
    return o
end

function Object:SayHi(input)
    if input == nil then
        input = ""
    else
        local temp = input
        input = " " .. temp
    end
    print("Hi!" .. input)
end

function Object:CallHiFunct()
    local temp = "Called from CallHiFunct"
    self:SayHi(temp)
end

function Object:PrintString()
    print(self.string) -- Variable named string from Object
end

object1 = Object:new() -- Returns new metatable to object1
object1:SayHi() -- Prints Hi!
object1:CallHiFunct() -- Prints Hi! Called from CallHiFunct
object1:PrintString() -- Prints Default

print()
print()

funct_object1 = object1.SayHi
funct_object1() -- Prints Hi!

funct2_object1 = object1.PrintString
funct2_object1() -- Error: attempt to index a nil value (local 'self')

funct2_object1 = object1:PrintString() -- if object1:PrintString Error: function arguments expected near 'funct2_object1'
funct2_object1() -- Error: attempt to call a nil value (global 'funct2_object1')

我正在尝试从对象/表中保存函数,但我遇到了问题。selfnil

我怎样才能正确地做到这一点以将函数与对象保持在一起?

.

我这样做的原因是因为我使用的是库中指定的函数,该函数接受函数作为参数。

我认为是这样的:

function Example(funct)
    funct() -- calls it here
end

确切地说,该函数实际上是:GUI:AddButton(arguments...):AddEventHandler(event, funct)

(event:激活时,激活时调用)funct

但我不太确定里面是什么。

无论如何。忽略此库是否可以将函数从“对象”保存到要从该变量调用的变量?

(我找不到任何答案。我已经被问过了,然后请将问题与答案联系起来。

谢谢。

函数 对象 lua lua-table

评论


答:

1赞 Oka 11/7/2023 #1

table:function(arguments)是纯粹的句法糖。table.function(table, arguments)

(在函数定义的主体中是隐式自我,当使用冒号语法定义时。)

如您所见,此任务

funct2_object1 = object1.PrintString

不携带任何信息,因此此函数调用object1

funct2_object1()

出错,寻找显式的第一个参数来填补 的角色。self

如果您调用了该函数,则该函数将按预期运行。funct2_object1(object1)


给定此回调样式函数

function Example(funct)
    funct() -- calls it here
end

听起来你想要的是围绕你的 OOP 风格的调用创建一个闭包,你可以通过用函数(匿名或其他方式)来封闭它。

例如:

local Object = {}

function Object:new(data)
    return setmetatable({ data = data }, { __index = self })
end

function Object:do_something()
    print('Hello from', self, self.data)
end

local thing = Object:new(42)

----

local function Example(funct)
    funct()
end

Example(function ()
    thing:do_something()
end)
Hello from  table: 0x55c65be628c0   42

评论

0赞 skrovno_CZ 11/8/2023
感谢您的回复。棒。现在它起作用了。我真的很感激。目前我没有意识到插入是可能的。现在我只需要调整一些东西,希望代码可以工作。function () thing:do_something() end