rawget.md 2.4 KB

#unity/日常积累

在 Lua 中,rawget 是一个函数,用于直接从表中获取值,而不触发元表的 __index 元方法。这在需要跳过元表逻辑、直接操作表内容时非常有用。

rawget(table, key)
  • table: 要查询的表。
  • key: 要查询的键。

返回值是对应键的值(如果存在),或者 nil(如果键不存在)。


使用场景

1. 跳过元表的 __index

当一个表设置了元表且定义了 __index,普通访问操作可能触发 __index 元方法。rawget 则绕过元表机制,直接查询表内的实际内容。

示例:

local t = {}
local mt = {
    __index = function(table, key)
        return "default"
    end
}
setmetatable(t, mt)

t.a = 10
print(t.a)            -- 输出:10
print(t.b)            -- 输出:default (触发了 __index)
print(rawget(t, "b")) -- 输出:nil    (直接查询表内容)

2. 在自定义逻辑中直接访问表内容

当需要通过函数自定义行为时,可以使用 rawget 获取表的原始值。

示例:

local t = { a = 1, b = 2 }
setmetatable(t, {
    __index = function(table, key)
        return rawget(table, key) or "fallback"
    end
})

print(t.a) -- 输出:1
print(t.c) -- 输出:fallback

注意事项

  1. 必须是有效的表: 如果传入的第一个参数不是表,会抛出错误:

    rawget(nil, "key")  -- 报错:attempt to index a nil value
    
  2. 不能用于新增键值对: rawget 仅用于读取表内的值,不能设置值。如果需要绕过元表机制新增键值对,应该使用 rawset

  3. key 的要求: 键可以是任何 Lua 支持的合法键类型(字符串、数字、表、函数等),但不能是 nil


对比:普通访问 vs. rawget

普通访问操作会触发元表的 __index,而 rawget 则仅查询表的实际内容:

local t = { x = 5 }
setmetatable(t, { __index = function() return 10 end })

print(t.x)           -- 输出:5 (表中有实际值)
print(t.y)           -- 输出:10 (触发 __index)
print(rawget(t, "y")) -- 输出:nil (表中无实际值)

rawget 是一个强大的工具,适用于需要直接访问表数据而绕过元表机制的场景,但使用时应注意保持代码的可维护性和逻辑一致性。