4

myFunc这些s有什么区别?

代码 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。他们的行为不一样。(例如,upvalue someVariable...有问题的:-S)

4

2 回答 2

5

[编辑:我误读了您的代码#2。]

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

代码#2 设置一个局部变量myFunc但是,由于 Lua 的规则,该局部变量只有在定义它的语句完成才会进入作用域。这使您可以执行以下操作:

local x = x or 5

x表达式中的 是先前声明的局部或全局。直到表达式被评估之后,新的x才会进入范围。x or 5

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

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

注意local function X相当于local X; X = function...local X = function...

于 2013-04-07T13:45:20.727 回答
2

Nicol 的回答大多是正确的,但有一点值得指出:

在代码 2MyFunc中不需要是全局变量,它可以是某个外部范围内的局部变量,这将成为您正在创建的此函数的上值(相同的注释也适用于代码 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 不会做你所期望的,因为它将使用 myFunclocal myFunc执行时可用的任何定义(这可能指向 MyFunc 的上值或全局变量)。4 将起作用,但仅仅是因为它将新创建的函数分配给(再次)一个上值或一个全局变量(并在函数体中引用相同的值)。

于 2013-04-07T20:15:49.213 回答