问题源自http://tylerneylon.com/a/learn-lua/ 教程包含代码:
Dog = {dog1 = 'original dog class'}
function Dog.new(self, ... )
newObj = {sound = 'woof'}
self.__index = self
return setmetatable(newObj, self)
end
function Dog.makeSound(self, ... )
print('I say' .. self.sound)
end
print('Dog=', Dog)
print('Dog.metatable=', getmetatable(Dog)) -- this will output nothing
myDog = Dog.new(Dog)
print('\nmyDog=', myDog)
print('myDog.metatable=', getmetatable(myDog))
myDog.makeSound(myDog)
这是教程中上述代码的结果:
wirelessprvnat-172-17-106-141:Programming frankhe$ th test2.lua
Dog= {
makeSound : function: 0x0a6cec20
dog1 : "original dog class"
new : function: 0x0a6cec00
}
Dog.metatable= nil
myDog= {
sound : "woof"
}
myDog.metatable= {
makeSound : function: 0x0a6cec20
__index :
{
makeSound : function: 0x0a6cec20
__index :
{
makeSound : function: 0x0a6cec20
__index :
{
makeSound : function: 0x0a6cec20
__index :
{
makeSound : function: 0x0a6cec20
__index : {...}
dog1 : "original dog class"
new : function: 0x0a6cec00
}
dog1 : "original dog class"
new : function: 0x0a6cec00
}
dog1 : "original dog class"
new : function: 0x0a6cec00
}
dog1 : "original dog class"
new : function: 0x0a6cec00
}
dog1 : "original dog class"
new : function: 0x0a6cec00
}
I saywoof
尽管教程中的实现成功打印了“I saywoof”,但 myDog 的元表显然不像我们预期的那样理想。因此我的解决方案如下(不同之处在 Dog.new 中):
function Dog.new(self, ... )
newObj = {sound = 'woof'}
return setmetatable(newObj, {__index = self})
end
我的解决方案的结果:
wirelessprvnat-172-17-106-141:Programming frankhe$ th test2.lua
Dog= {
makeSound : function: 0x0d7f2978
dog1 : "original dog class"
new : function: 0x0d7f2958
}
Dog.metatable= nil
myDog= {
sound : "woof"
}
myDog.metatable= {
__index :
{
makeSound : function: 0x0d7f2978
dog1 : "original dog class"
new : function: 0x0d7f2958
}
}
I saywoof
我的代码打印出“I saywoof”并具有更精确的表结构。我想知道哪个实现是正确的,教程中的还是我的?另外,我想知道为什么教程中的代码会生成 Dog 的元表的迭代定义。