如果 __index 未在元表中实现,则尝试调用 nil 值(方法 '...')
attempt to call a nil value (method '...') if __index not implemented in metatable
Lua 没有提供一种独特的 OOP 方式。
使用 setmetatable
可以有很多选择。
这是我尝试过的:
Person={}
function Person.__call(cls,name)
return setmetatable({name=name},cls)
end
function Person:say(what)
print(self.name..'> '..what)
end
setmetatable(Person,Person)
p=Person('Fred')
p:say('hello') -- 18
给出错误:
18: attempt to call a nil value (method 'say')
我可以加:
function Person.__index(cls,k)
return Person[k]
end
然后上面的代码可以正常工作,但是我不明白为什么当 Person
本身已经是元表时找不到该方法。
您需要实现 __index 元值才能中继索引访问操作。仅有一个 metatable 是不够的。
另请注意,建议在将 table 用作元table 之前实现所有元方法。
参考Lua 5.4 Reference Manual 2.4 Metatables and Metamethods
__index: The indexing access operation table[key]. This event happens when table is not a table or when key is not present in table. The
metavalue is looked up in the metatable of table.
The metavalue for this event can be either a function, a table, or any
value with an __index metavalue. If it is a function, it is called
with table and key as arguments, and the result of the call (adjusted
to one value) is the result of the operation. Otherwise, the final
result is the result of indexing this metavalue with key. This
indexing is regular, not raw, and therefore can trigger another
__index metavalue.
__index
就是那个元值。因此,如果您不提供该元值,Lua 应该做什么?
在下面的例子中元值是Person
。
所以当我调用a:sayName()
时,Lua会发现a.sayName
是nil。它将检查 a
的元 table Person
中是否存在 __index
元值。有,在这种情况下,它是一个名为 Person
的 table,因此它将使用键 "sayName"
索引该人,从而导致以下函数调用:Person["sayName"](a)
local Person= {}
Person.__index = Person
setmetatable(Person, {
__call = function (cls, ...)
return cls:_init(...)
end,
})
function Person:_init(name)
local o= setmetatable({}, self)
o.name = name
return o
end
function Person:sayName()
print(self.name)
end
local a = Person("Lisa")
a:sayName()
Lua 没有提供一种独特的 OOP 方式。
使用 setmetatable
可以有很多选择。
这是我尝试过的:
Person={}
function Person.__call(cls,name)
return setmetatable({name=name},cls)
end
function Person:say(what)
print(self.name..'> '..what)
end
setmetatable(Person,Person)
p=Person('Fred')
p:say('hello') -- 18
给出错误:
18: attempt to call a nil value (method 'say')
我可以加:
function Person.__index(cls,k)
return Person[k]
end
然后上面的代码可以正常工作,但是我不明白为什么当 Person
本身已经是元表时找不到该方法。
您需要实现 __index 元值才能中继索引访问操作。仅有一个 metatable 是不够的。
另请注意,建议在将 table 用作元table 之前实现所有元方法。
参考Lua 5.4 Reference Manual 2.4 Metatables and Metamethods
__index: The indexing access operation table[key]. This event happens when table is not a table or when key is not present in table. The metavalue is looked up in the metatable of table.
The metavalue for this event can be either a function, a table, or any value with an __index metavalue. If it is a function, it is called with table and key as arguments, and the result of the call (adjusted to one value) is the result of the operation. Otherwise, the final result is the result of indexing this metavalue with key. This indexing is regular, not raw, and therefore can trigger another __index metavalue.
__index
就是那个元值。因此,如果您不提供该元值,Lua 应该做什么?
在下面的例子中元值是Person
。
所以当我调用a:sayName()
时,Lua会发现a.sayName
是nil。它将检查 a
的元 table Person
中是否存在 __index
元值。有,在这种情况下,它是一个名为 Person
的 table,因此它将使用键 "sayName"
索引该人,从而导致以下函数调用:Person["sayName"](a)
local Person= {}
Person.__index = Person
setmetatable(Person, {
__call = function (cls, ...)
return cls:_init(...)
end,
})
function Person:_init(name)
local o= setmetatable({}, self)
o.name = name
return o
end
function Person:sayName()
print(self.name)
end
local a = Person("Lisa")
a:sayName()