我正在尝试将函数与保护功能包装在一起。
我的代码:
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:很抱歉,我的问题很愚蠢。
答案 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
这就是您所需要的吗?无法直接访问foo
和goo
函数。
由此引出的下一个想法是不通过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()
的值,假定它是一个函数,并且不带参数调用它。执行该函数,该函数评估函数定义以获得函数值并将其设置为全局变量Lib
; foo
同样;并返回全局变量goo
(大概是self
)的值。返回值被丢弃,因为该调用不执行任何操作。
然后执行:
nil
使用全局变量print(foo(3, 2))
的值,假定它是一个函数并使用两个参数调用它。这将执行返回5的函数。然后使用全局变量foo
的值,假定它是一个函数,并使用值5进行调用。返回值将被丢弃,因为该调用不会执行任何操作它。
其他答案可将您引向您可能想要做的事情。您可以使用这些原则评估他们的建议。