如何在lua类中编写私有函数

时间:2016-01-13 21:54:43

标签: lua

我试着写lua" class"有私人功能,如:

local myTable = {}

function myTable.func()
    private()
end

local function private()
    print(":O")
end

return myTable

让我们说生病需要" myTable"然后运行myTable.func()生成错误,该错误表示" private"没有定义。

我找到了两种方法来解决这个问题:

1)移动"私人"在" func"之前的功能 2)"定义"本地私人之前" func"并将私人签名更改为" function private"。

但我很困惑他们为什么工作,哪种是常见的方式,很高兴帮助理解,ty:)

4 个答案:

答案 0 :(得分:3)

  

这是常用的方法

工作和两者都是可取的。在你有两个相互调用的函数并且两个函数都需要本地但不在表中的情况下,需要第二种方法。

可以总是使用第二种风格,从而保持一致性,尽管它可能不像您需要转到代码中的其他位置以查看您的功能是否是本地的。 / p>

然而,为了便于阅读和更短的代码我会使用第一种方法,所以我不需要单独的声明"我当地的职能。

  

我对他们为什么工作感到困惑

原始代码不起作用的原因是因为局部变量范围。 来自lua参考手册:

  

Lua是一种词汇范围的语言。 局部变量的范围   从声明后的第一个声明开始并持续到   包含最内层块的最后一个非void语句   声明。

因此,在原始代码中,变量private被定义为定义它之后的行中的函数。并且代码失败是因为您尝试在之前的代码中使用它。

这些方法有效,因为它们都将局部变量范围移动到使用变量的代码上方。

您可能希望阅读参考手册中的局部变量和范围界定:

答案 1 :(得分:0)

首先:在您的代码段中,我不清楚"类"是,因为myTable只是一个对象。如果你把它放在一个模块中并require,你就得到一个对象。

可以做这样的事情:

local function MyTable() -- constructor
    local function private()
        print(":O")
    end
    return {
        func = function()
            private()
        end
    }
end

local m = MyTable()
m.func()

这可能不是通常在Lua中进行OOP的可能,但private显然是私有的。

答案 2 :(得分:0)

你基本上需要这样的东西:

local function Bezier(x1,y1,x2,y2,x3,y3)
--Private
local inf = 1/0
local x1 = x1
local y1 = y1
local x2 = x2
local y2 = y2
local x3 = x3
local y3 = y3

local maxY = y1 > y2 and (y1 > y3 and y1 or y3) or y2 > y3 and y2 or y3
local minY = y1 < y2 and (y1 < y3 and y1 or y3) or y2 < y3 and y2 or y3

local maxX = x1 > x2 and (x1 > x3 and x1 or x3) or x2 > x3 and x2 or x3
local minX = x1 < x2 and (x1 < x3 and x1 or x3) or x2 < x3 and x2 or x3

local xc = (x3 - 2*x2 + x1)
local xb = 2*(x2 - x1)
local yc = (y3 - 2*y2 + y1)
local yb = 2*(y2 - y1)

--Public
local self = {}

--Render
self.render = function(resolution)
    local path = {}
    local num = 1
    for index=0, 1, 1/resolution do
        path[num] = {(1-index)^2*x1+2*(1-index)*index*x2+index^2*x3, (1-index)^2*y1+2*(1-index)*index*y2+index^2*y3}
        num = num + 1
    end
    return path
end
--Point
function self.point(index)
    return {(1-index)^2*x1+2*(1-index)*index*x2+index^2*x3, (1-index)^2*y1+2*(1-index)*index*y2+index^2*y3}
end
--Get x of patricular y
function self.getX(y)
    if y > maxY or y < minY then
        return
    end
    local a = y1 - y
    if a == 0 then
        return
    end
    local b = yb
    local c = yc
    local discriminant = (b^2 - 4*a*c )

    if discriminant < 0 then
        return
    else
        local aByTwo = 2*a
        if discriminant == 0 then
            local index1 = -b/aByTwo
            if 0 < index1 and index1 < 1 then
                print("=====",y,1,maxY,minY)
                return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3
            end
        else
            local theSQRT = math.sqrt(discriminant)
            local index1, index2 = (-b -theSQRT)/aByTwo, (-b +theSQRT)/aByTwo
            if 0 < index1 and index1 < 1 then
                if 0 < index2 and index2 < 1 then
                    print("=====",y,2,maxY,minY)
                    return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3, (1-index2)^2*x1+2*(1-index2)*index2*x2+index2^2*x3
                else
                    print("=====",y,1,maxY,minY)
                    return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3
                end
            elseif 0 < index2 and index2 < 1 then
                print("=====",y,1,maxY,minY)
                return (1-index2)^2*x1+2*(1-index2)*index2*x2+index2^2*x3
            end
        end
    end     
end
--Get y of patricular x
function self.getY(x)
    if x > maxX or x < minX then
        return 
    end
    if maxX == minX and x == minX then
        return minY, maxY
    end
    local index1, index2, buffer1, buffer2
    local a = (x1 - x)
    if a == 0 then
        return
    end
    local b = xb
    local c = xc
    local discriminant = b^2 - 4*a*c 
    if discriminant < 0 then
        return
    else
        local aByTwo = 2*a
        local theSQRT = math.sqrt(discriminant)
        if discriminant == 0 then
            local index1 = -b/aByTwo
            return (1-index1)^2*y1+2*(1-index1)*index1*y2+index1^2*y3
        else
            local index1, index2 = (-b - theSQRT)/aByTwo, (-b + theSQRT)/aByTwo
            return (1-index1)^2*y1+2*(1-index1)*index1*y2+index1^2*y3, (1-index2)^2*y1+2*(1-index2)*index2*y2+index2^2*y3
        end
    end
end
--Scanline render
function self.scanRender()
    local path = {}
    local counter = 1
    local fX, sX
    local a = (y3 - 2*y2 + y1)
    local b = 2*(y2 - y1)
    for i=minY, maxY do
        fX, sX = self.getX(i,a,b)
        if fX then
            path[counter] = fX
            path[counter+1] = i
            counter = counter + 2
            if sX then
                path[counter] = sX
                path[counter+1] = i
                counter = counter + 2
            end
        end
    end
    return path
end
--More efficient
--Self
return self
end

通过调用bezier,您将获得一个Bezier对象。此对象将能够访问自身表中的所有私有属性和公共接口。

答案 3 :(得分:0)

我创建了这个示例代码:

local object = {}

do -- Creates Scope

    -- Private Scope

    local fire_rate = 5

    -- Public Scope

    function object:load()

    end

    function object:update()

    end

    function object:draw()

    end

    function object:setFireRate(rate)
        fire_rate = rate
    end

    function object:getFireRate()
        return fire_rate
    end
end

return object

希望这有帮助。