如何在Lua中的函数中调用函数

时间:2018-07-18 02:08:07

标签: lua

我正在尝试将函数与保护功能包装在一起。

我的代码:

function Lib()
  function self:foo(x, y) return x+y end
  function self:goo(x, y) return x-y end
end
print(Lib():foo(3, 2))

我希望得到5,但出现以下错误。

attempt to index a nil value (global 'self')

我的代码有什么问题以及如何解决?

已添加:有人可以将其与使用Lib = {}进行比较吗?我正在考虑用函数包装函数,因为编写self:比编写Lib.更容易维护,后者可以在以后更改。我想知道我的想法是否有意义。


编辑:好的,我刚刚发现了这个方法。

function Lib()
  function foo(x, y) return x+y end
  function goo(x, y) return x-y end
  return self
end
Lib()
print(foo(3, 2))

但是我不明白为什么。函数内部的函数不能受到保护吗?

PS:很抱歉,我的问题很愚蠢。

3 个答案:

答案 0 :(得分:3)

function Lib()
   local function foo(x, y) return x+y end
   local function goo(x, y) return x-y end

   interface = {}
   interface.foo = foo
   interface.goo = goo

   return interface
end

所以:

l = Lib()
print(l.foo(3, 2))

将打印5

这就是您所需要的吗?无法直接访问foogoo函数。

由此引出的下一个想法是通过goo公开interface函数,而仅在foo或其他一些函数中使用功能。在这种情况下,goo将是一个实现细节(一个私有函数),而不是通过对象接口公​​开的。

答案 1 :(得分:2)

隐式self参数仅存在于:方法函数的主体中。

由于Lib没有用:定义,因此没有self变量。

您可以改为创建一个工厂/构造函数,该工厂/构造函数将创建一个空白实例并附加方法:

function new(factor)
    local instance = {factor = factor}

    function instance:multiply(n)
        return self.factor * n
    end

    return instance
end

local m = new(5)
print(m:multiply(6)) --> 3

如果您确实想要拥有许多实例的 class ,而不是为每个实例定义一个函数,则可以将一个元表附加为“自动”附加所有属性:

local Class = {}

function Class.new(factor)
    local instance = {factor = factor}

    return setmetatable(instance, {__index = Class})
end

function Class:multiply(n)
    return self.factor * n
end

local m = Class.new(5)
print(m:multiply(6)) --> 30

答案 2 :(得分:1)

函数是执行函数定义时创建的值。任何变量都可以引用函数值。

因此,尽管函数定义可能在另一个函数体内,但函数值不在函数内部。它可以通过任何表达式,表键和字段以及引用它的变量来使用。

变量是全局变量或局部变量(包括参数)。如果变量的名称先前未声明为局部,则为全局。因此,执行以下代码:

fn transfer(tx: &Mutex<i32>, rx: &Mutex<i32>, amount: i32) -> () {
    loop {
        // Attempt to lock both mutexes
        let mut tx = tx.try_lock();
        let mut rx = rx.try_lock();

        // If both locks were successfull,
        // i.e. if they currently are not
        // locked by an other thread
        if let Ok(ref mut tx) = tx {
            if let Ok(ref mut rx) = rx {
                // Perform the operations needed on
                // the values inside the mutexes
                **tx -= amount;
                **rx += amount;

                // Exit the loop
                break;
            }
        }
        // If at least one of the locks were
        // not successful, restart the loop
        // and try locking the values again.

        // You may also want to sleep the thread
        // here for a short period if You think that
        // the mutexes might be locked for a while.
    }
}

将全局变量function Lib() function foo(x, y) return x+y end function goo(x, y) return x-y end return self end 设置为通过评估函数定义创建的函数值。到此为止。

然后执行:

Lib

使用全局变量Lib() 的值,假定它是一个函数,并且不带参数调用它。执行该函数,该函数评估函数定义以获得函数值并将其设置为全局变量Libfoo同样;并返回全局变量goo(大概是self)的值。返回值被丢弃,因为该调用不执行任何操作。

然后执行:

nil

使用全局变量print(foo(3, 2)) 的值,假定它是一个函数并使用两个参数调用它。这将执行返回5的函数。然后使用全局变量foo的值,假定它是一个函数,并使用值5进行调用。返回值将被丢弃,因为该调用不会执行任何操作它。

其他答案可将您引向您可能想要做的事情。您可以使用这些原则评估他们的建议。