Lua中的本地函数可以替换或覆盖自身吗?

在 Lua 中,是否可以在一个局部函数内部替换它自己?例如:

local function emptyFunction(arg)
    return
end

local function exampleFunction(arg)
    local result, err = io.open("/tmp/BadFile","w")
    if result == nil then
        print(err)
        exampleFunction = emptyFunction
        return
    end
    io.close(result)
end
点赞
用户5016443
用户5016443

什么都不会阻止你这样做。在 Lua 中,本地或非本地函数名称实际上是指向函数本身的变量名称。

因此,在这两种情况下,

local function f1()
  ...
end

local f1 = function()
               ...
          end

f1 都在函数体的作用域范围内。

然而,这种替换不会改变任何外部引用

function f1()
   print("f1")
end

function f2()
    print("f2")
    f2 = f1
end

f = f2

f1(); f2(); f2() f();

输出将变为

f1
f2
f1
f2

请注意,如果在声明中添加 local 关键字,将不会改变任何内容。

2015-11-04 09:01:26
用户1695906
用户1695906

在函数内部重新定义函数,需要在变量分配函数之前先声明一个对函数的引用。

第一个例子-错误的做法-不工作,因为 "fx" 在 fx 内部 _不在范围之内_,就像我直觉(对我来说)告诉我一样。

坦率地说,我不知道如何精确描述函数内部的 "fx" 表示什么——但它似乎是一个全局变量,在某种程度上处于比 'global local' 声明更全局的作用域中。

在全局空间中,我一直认为这两者是等价的:

foo = 'bar';
local foo = 'bar';

严格来说,它们显然并不真正等价,_如果_你有一种方法可以访问两者。这个第一个例子正是这么做的,原因如下:

当你这样做……

local myfunc = function () ...

你实际上正在首先声明一个匿名函数,然后声明 "myfunc",最后将 "myfunc" 设置为你刚刚创建的匿名函数的引用。直到函数开始存在的那一刻,"local myfunc" 还不存在,因为声明该语句尚未实际执行。 (至少,这是我观察到的。)

这是一个不起作用的版本,它说明了这一点:

local fx = function ()
    print(fx);
    print("inside the original fx")
    fx = function() print "I was redefined" end
end

function f2()
     print("f2")
     f2 = fx
end

f = f2

print(fx);

fx(); fx(); f2(); f2() f();

function: 0x21a6140// "global local fx" 中原始 "fx" 的引用
nil                     // 内部 "fx" -- 在第一次迭代中未设置,因此它不能是同一个变量
inside the original fx  //因此不能是相同的变量
function: 0x21a6510 // 现在已经设置, 但是指向新的函数。但是 "global local fx" 没有包含我们的新函数。
inside the original fx  // 不能是相同的变量
f2
function: 0x21a6510 // 重定义它正好按预期工作
inside the original fx
f2

第二个例子,我们首先声明本地 fx,然后将其设置为对函数的引用。没有其他更改。

local fx;       // 在分配之前声明
fx = function ()
    print(fx);
    print("inside the original fx")
    fx = function() print "I was redefined" end
end

function f2()
     print("f2")
     f2 = fx
end

f = f2

print(fx);

fx(); fx(); f2(); f2() f();

function: 0x2188e50      // 原始函数
function: 0x2188e50      // 同一个引用,因此此函数在函数内部处于范围之内
inside the original fx
I was redefined          // 重定义它正好按预期工作
f2
I was redefined
f2

所以,是的,有一种方法。您需要声明一个全局本地变量,并随后将其设置为对函数的引用,以便在试图重新定义它的函数中处于范围之内。

同样, f2 函数不能重新定义自身。它仅在 f2() 运行时重新定义 f2 的含义,内部。

2015-11-04 15:28:24