【问题标题】:Classes in Lua, how does it workLua 中的类,它是如何工作的
【发布时间】:2014-11-27 07:33:13
【问题描述】:

我是 Lua 的新手,我正在尝试了解它的 OO 部分,例如:

lkw = {}
lkw.la= 0

function lkw:func(ge)
    self.la = self.la + ge
end

function lkw:new()
    local res = {}
    setmetatable(res, self)
    self.__index = self
    return res
end

mylkw = lkw:new()

在本例中,“类”lkw 可以使用 new 创建对象,但 selfindex 是什么意思? 应该将self 视为java/C++ 中的this,索引是什么?

【问题讨论】:

  • self: 的函数定义在手册的Section 2.5.9 中进行了解释(以及在 PiL 等中)。 __indexSection 2.8 - Metatables 中解释。
  • @EtanReisner 所以我可以使用 : 代替使用 slef 作为第一个参数,对吧?
  • 我不明白这个问题。当您使用 : 定义函数时,“自动”获取一个 self 参数(作为第一个参数)。当您使用 : 调用函数时,: 左侧的项目将“自动”作为第一个参数传递。
  • 抱歉,我阅读了第 2.8 节,但仍然不明白 self 是什么意思或做什么
  • Lua 编程 一书讨论了这一点。您可能应该阅读它。第一版是免费在线的(尽管是为 lua 5.0 编写的,但仍然很重要)。

标签: lua


【解决方案1】:

这种 OOP 风格在 Lua 中很常见。我不喜欢它,因为它对我来说不够明确,但让我试着解释一下。

有两件令人困惑的事情:在函数定义中使用: 糖,以及使用“类”作为其实例的元表。

首先,function a:b(...)a.b = function(self, ...) 相同,所以让我们去掉所有的糖:

lkw = {}
lkw.la = 0

lkw.func = function(self, ge)
    self.la = self.la + ge
end

lkw.new = function(self)
    local res = {}
    setmetatable(res, self)
    self.__index = self
    return res
end

mylkw = lkw.new(lkw)

现在,这是“原型继承”。 lkwmylkw 等实例的“原型”。这与“类”相似但略有不同。

当调用new 构造函数时,lkw 作为self 参数传递。

构造函数的第二行和第三行很奇怪。这可能更容易理解:

lkw.new = function(self)
    local res = {}
    setmetatable(res, {__index = lkw})
    return res
end

即:如果我们在实例中没有找到某些东西,我们会在原型中寻找它。

这解释了func 的工作原理。第一次调用时,实例将不包含la 键,因此将使用lkw.la

代码之所以不是这样写的原因是奇怪的结构允许“原型继承”:您可以在mylkw 上调用“new”并获得“实例的实例”(即在原型继承中,实例和子类是同一件事)。

我认为这是一个非常令人困惑的功能。作为参考,这是关于我将如何编写做同样事情的代码,没有继承:

local methods = {
    func = function(self, ge)
        self.la = self.la + ge
    end
}

local lkw = {
    new = function()
        return setmetatable({la = 0}, {__index = methods})
    end
}

local mylkw = lkw.new()

【讨论】:

    猜你喜欢
    • 2017-06-20
    • 2022-01-28
    • 2013-08-01
    • 1970-01-01
    • 2022-10-15
    • 2012-10-26
    • 2012-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多