1

由于某些变量位于“外部”范围内,以下 Lua 4.0 脚本失败。我可以用什么不同的方法来解决这个问题?如果可能的话,我想避免将事情完全放在全局范围内。谢谢。

function flokalAdd(iNx, iNy, iXmin, iSym, fEcc, bInside, fScale)
    TWO_PI = 2 * PI;
    iSx = 4;
    iSy = 4;
    function pow(fA, fB)
        return fA^fB
    end
    function mag(fX, fY)
        return dist(fX, fY, 0, 0)
    end
    function dist(fX1, fY1, fX2, fY2)
        return sqrt(pow(fX2 - fX1, 2) + pow(fY2 - fY1, 2))
    end
    function norm()
        local fY1 = 0;
        local fX1 = 0;
        local fX2 = exp(fX1) * cos(deg(fY1));
        local fY2 = exp(fX1) * sin(deg(fY1)) + fEcc;
        local fD = 0;
        if (bInside == 1) then
            fD = pow(mag(fX2, fY2),  1/iSym);
        else
            fD = pow(mag(fX2, fY2), -1/iSym);
        end
        local fArg = rad(atan2(fX2, fY2)) * -1/iSym;
        local fX3 = fD * cos(deg(fArg))/TWO_PI;
        local fY3 = fD * sin(deg(fArg))/TWO_PI;
        return mag(fX3, fY3)
    end
    function fn(fX, fY)
        local aP = {};
        local fX1 = exp(fX) * cos(deg(fY));
        local fY1 = exp(fX) * sin(deg(fY)) + fEcc;
        local fD = 0;
        if (bInside == 1) then
            fD = pow(mag(fX1, fY1),  1/iSym);
        else
            fD = pow(mag(fX1, fY1), -1/iSym);
        end
        local fArg = rad(atan2(fX1, fY1)) * -1/iSym;
        for i = 0, iSym - 1 do
            local fX2 = fD * cos(deg(fArg + i * TWO_PI/iSym))/TWO_PI;
            local fY2 = fD * sin(deg(fArg + i * TWO_PI/iSym))/TWO_PI;
            aP[i + 1] = {fX2, fY2};
        end
        return aP
    end
    function lines(aP1, aP2)
        for i = 0, iSym - 1 do
            local fX1 = aP1[i + 1][0 + 1];
            local fY1 = aP1[i + 1][1 + 1];
            local fX2 = aP2[i + 1][0 + 1];
            local fY2 = aP2[i + 1][1 + 1];
            --addPebble(<sPebbleType>, <tPosition>, ?, ?, ?)
            --addPebble("Pebble_2", {fX1 * fScale/fNorm, 0 * fScale/fNorm, fY1 * fScale/fNorm,}, 0, 0, 0)

            -----------------------
            -- DO SOMETHING HERE --
            -----------------------
        end
    end
    -- calculate the distance from the origin to the center of each eye, then use it to normalize the shape to within 1 unit of the center
    fNorm = norm();
    for i = 0, iNy - 1 do
        local fY = i * TWO_PI/iNy;
        for j = iXmin * iSx, iNx * iSx - 1 do
            local fX1 = j * TWO_PI/iNx/iSx;
            local fX2 = (j + 1) * TWO_PI/iNx/iSx;
            lines(fn(fX1, fY), fn(fX2, fY))
        end
    end
    for i = iXmin, iNx do
        local fX = i * TWO_PI/iNx;
        for j = 0, iNy * iSy - 1 do
            local fY1 = j * TWO_PI/iNy/iSy;
            local fY2 = (j + 1) * TWO_PI/iNy/iSy;
            lines(fn(fX, fY1), fn(fX, fY2))
        end
    end
end



flokalAdd(16, 16, 12, 5, 256, false, 20000)
4

1 回答 1

3

发生这种情况是由于Lua 4.0 范围规则

函数作用域有一个特殊的限制,即不能访问外部作用域(除了全局作用域)。这适用于任何函数,但在嵌套函数的情况下最为明显,您可能希望访问封闭范围的局部变量。

在您的代码fEcc中定义在 function 范围内flokalAdd,因此无法从内部norm函数访问它。
您可以使用 upvalues 解决此问题:

添加了向上值以解决函数范围限制。使用 % 为外部范围变量引用添加前缀会在函数实例化时生成该变量的副本。只有包含函数的直接作用域和全局作用域才能以这种方式访问​​。

看代码,好像按值复制是可以的。这里是固定版本。

于 2013-09-05T11:07:29.467 回答