我可以覆盖Lua表的返回值吗?

时间:2014-07-17 20:55:58

标签: syntax lua override lua-table meta-method

当没有键引用时,表是否可以返回特定值而不是对自身的引用?

假设我有下表:

local person = {
    name  = "Kapulani",
    level = 100,
    age   = 30,
}

在Lua中,我可以很容易地引用“person.name”,“person.level”或“person.age”并获得预期的值。但是,在某些情况下,我可能只想引用“person”而不是获取“table:”而是要返回“person.name”的值。

换句话说,我希望person.x(或person [x])从表中返回相应的条目,但是没有键的人返回person.name(或人[“name”]的值])。是否有一种我无法找到的机制?

我对metatables没有成功,因为__index仅适用于密钥不存在的情况。如果我把“人”放在一个单独的表中,我可以提出:

local true_person = {
    ... -- as above
}

local env_mt = {
    __index = function(t, k)
        if k == 'person' then
            return true_person
        end
    end
}

local env = setmetatable( {}, env_mt )

这让我可以使用__index做一些特殊的处理,除了我无法通过__index()告诉我是否收到env.person请求(我想要返回true_person)。 name)或env.person [key](我希望将true_person作为表返回,以便可以正确访问'key'。)

有什么想法?我可以采用不同的方式,但希望我可以按照这些方法来解决这个问题。

2 个答案:

答案 0 :(得分:2)

通过设置__tostring metatable条目,可以在将表用作字符串时执行此操作:

$ cat st.lua
local person = {
    name  = "Kapulani",
    level = 100,
    age   = 30,
}

print(person)
print(person.name)
print(person.age)

setmetatable(person, {__tostring = function(t) return t.name end})
print(person)

$ lua st.lua
lua st.lua
table: 0x1e8478e0
Kapulani
30
Kapulani

答案 1 :(得分:1)

我不确定你所要求的是一个好主意,因为它在组合性面前飞逝。通常人们会期望以下两个程序做同样的事情,但你希望它们表现不同

print(person.name)

local p = person
print( p.name )

它也不是很清楚如何分配。 person.age = 10应更改年龄,但person = otherPerson应更改对perrson的引用,而不是年龄。

如果您不关心组合性并且是onyl读取数据,那么解决问题的更直接方法是使用查询函数来接收以字符串编码的字段

query("person.age")   -- 17
query("person.name")  -- "hugomg"
query("person")       -- 17; query gets to default to whatever it wants.

为了使语法更轻量,您可以省略可选的括号

q"person.age"
q"person"

或者您可以在全局表__index上扩展_G元方法

setmetattable(_G, { __index = function(self, key) return query(key) end })

print ( person_age )  -- You will need to use "_" instead of "." for the
                      -- query to be a valid identifier.