Lua 构造函数中的 self

问题描述 投票:0回答:1

那里!

抱歉,这不是一个具体的问题。

在《Programming in Lua, 4th Edition》中可以看到以下代码:

Account = {balance = 0}

function Account:new (o)
    o = o or {}
    self.__index = self
    setmetatable(o, self)
    return o
end

我的困惑是线

self.__index = self

这意味着

Account
在创建实例时成为自己的
__index
only :

a = Account:new()

如果你仔细想想,这会很令人困惑。我知道这样做是为了轻松增加继承深度,这样你就可以做到:

AccountGold = Account:new({cashBackPercentage = 5})
AccountPlatinum = AccountGold:new({personalSupport = true})

但对我来说这

Account.__index = Account

看起来更具可读性。

更令人困惑。例如,查看 yui 库:

local Button = setmetatable({
    __call = function(cls, args) return cls:new(args) end
}, Widget)
Button.__index = Button


function Button:new(args)
    self = setmetatable(args, self)

    self.text = self.text or ""
    self.align = self.align or 'center'
    self.valign = self.valign or 'center'
    self.active = false
    if not self.notranslate then
        self.text = T(self.text)
    end
    return self
end

看这个:

self = setmetatable(args, self)

读作:

Button = setmetatable(args, Button)

这意味着每次创建新实例时,

Button
表都会更改。

这是一种常见做法吗?您能对此发表评论吗?

oop lua constructor factory
1个回答
0
投票

你读的不对,

self = setmetatable(args, self)
并没有改变
Button
,只是将参数
self
覆盖为
setmetatable
的返回值,所以等价于下面的代码:

local t = setmetatable(args, self)
t.text = t.text or ""
...

隐式参数

self
是动态的,它的值取决于函数的调用方式。对于
Account:new(....)
来说,
self
就是
Account
,对于
AccountGold:new(....)
来说,
self
就是
AccountGold
,这样就可以用单个函数实现继承。

© www.soinside.com 2019 - 2024. All rights reserved.