3

在没有键的情况下引用表时,是否有可能返回特定值而不是对自身的引用?

假设我有下表:

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(或 person["name"])的值。有没有我找不到的机制?

我对元表没有成功,因为 __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”)。

有什么想法吗?我可以以不同的方式处理这个问题,但希望我可以沿着这些思路处理这个问题。

4

2 回答 2

2

当表被用作字符串时,您可以通过设置__tostring元表条目来执行此操作:

$ 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
于 2014-07-17T21:07:34.743 回答
1

我不确定您所要求的是否是一个好主意,因为它与组合性背道而驰。通常人们会期望以下两个程序做同样的事情,但你希望它们表现不同

print(person.name)

local p = person
print( p.name )

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

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

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.
于 2014-07-18T05:31:19.733 回答