命名函数与匿名函数(Lua)之间的区别

这三个myFunc之间有什么区别?

代码1

function wrapper()
    local someVariable = 0;
    function myFunc(n)
        if n > 0 then return myFunc(n-1) end
    end
    return myFunc;
end

代码2

function wrapper()
    local someVariable = 0;
    local myFunc = function(n)
        if n > 0 then return myFunc(n-1) end
    end
    return myFunc;
end

代码3

function wrapper()
    local someVariable = 0;
    local myFunc;
    myFunc = function(n)
        if n > 0 then return myFunc(n-1) end
    end;
    return myFunc;
end

因为在myFunc中引用函数名称myFunc时,它们的行为不同。(例如:上值someVariable...存在问题:-S)

点赞
用户734069
用户734069

代码#1将myFunc的全局值设置为函数。因此,每次调用wrapper时,你都会将这个全局值设置为新的值。此外,对你的myFunc调用的任何引用都将指向这个全局变量(可修改的),而不是局部变量(它将是闭包的上值)。

代码#2设置一个局部变量myFunc。但是,由于Lua的规则,只有在定义该变量的语句完成后,该局部变量才会进入作用域。这允许你做这样的事情:

local x = x or 5

表达式中的x是一个先前声明的局部或全局变量。新的x直到评估完成x或5表达式后才进入作用域。

对于函数定义也是一样的。因此,对myFunc的任何引用都将指向全局变量,而不是局部变量。

代码#3创建一个局部变量myFunc。然后它将一个函数设置到该变量中。因为函数是在局部变量进入作用域之后创建的,所以函数中对myFunc的任何引用都将引用局部变量,而不是全局变量。

请注意,local function X等同于local X; X = function...,而不是local X = function...

2013-04-07 13:45:20
用户1442917
用户1442917

Nicol 的答案大部分是正确的,但需要指出一件事:

在 Code 2 中,MyFunc 不需要是一个全局变量,它可以是外部作用域中的本地变量,这将成为你创建的这个函数的一个 upvalue。(相同的评论也适用于 Code 1)。例如,这将打印 100

local function myFunc(n) return 100 end
function wrapper()
    local someVariable = 0;
    local myFunc = function(n)
        if n > 0 then return myFunc(n-1) end
    end
    return myFunc;
end
print(wrapper()(1))

因此,总结一下,有四种定义 myFunc 的方法:

  1. local myFunc; myFunc = function(n) ... return myFunc(n-1) end
  2. local function myFunc(n) ... return myFunc(n-1) end
  3. local myFunc = function(n) ... return myFunc(n-1) end
  4. myFunc = function(n) ... return myFunc(n-1) end

1 和 2 是完全等效的。3 不会像你期望的那样工作,因为它将使用 local myFunc 执行时可用的 myFunc 的任何定义(可能指向 MyFunc 的 upvalue 或全局变量)。4 会生效,但仅因为它将新创建的函数分配给(再次)一个 upvalue 或全局变量(并在函数体中引用相同的值)。

2013-04-07 20:15:49