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

我正在尝试使用函数来保护函数。

我的代码:

function Lib()
  function self:foo(x, y) 返回 x+y end
  function self:goo(x, y) 返回 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) 返回 x+y end
  function goo(x, y) 返回 x-y end
  return self
end
Lib()
print(foo(3, 2))

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

PS:如果我的问题很愚蠢,请原谅我。

点赞
用户4403144
用户4403144
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 函数。

下一个想法是 通过 interface 公开 goo 函数,而是只在 foo 或其他函数中使用它。在这种情况下,goo 将是一个实现细节(私有函数),不通过对象接口公开。

2018-07-18 03:00:49
用户2616735
用户2616735

一个隐式的 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)) --> 30

如果您真的想要一个您有多个实例的 _类_,而不是为每个实例定义一个函数,您可以附加一个元表来“自动”附加所有属性:

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
2018-07-18 03:08:08
用户2226988
用户2226988

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

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

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

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

将全局变量Lib设置为通过评估函数定义创建的函数值。到这里就完成了。

然后,执行:

Lib()

使用全局变量Lib的值,假设它是一个函数,并在没有参数的情况下调用它。这将执行函数,该函数评估函数定义以获得函数值,并将其设置为全局变量foo;类似地,也是针对goo;并返回全局变量self的值(可能为nil)。返回值被丢弃,因为调用没有对其进行任何操作。

然后,执行:

print(foo(32))

使用全局变量foo的值,假设它是一个函数,并使用两个参数调用它。这将执行函数,它返回5。然后它使用全局变量print的值,假设它是一个函数,并使用值5调用它。返回值被丢弃,因为调用没有对其进行任何操作。

其他答案都引导你去做你想做的事情。你可以使用这些原则评估他们所建议的内容。

2018-07-19 00:00:00