您当前的位置: 首页 >  Jave.Lin

lua __index 测试

Jave.Lin 发布时间:2020-09-26 12:14:30 ,浏览量:6

有一个普通的 table

-- 普通表
local normal_tbl = { pro = 1 }

直接打印他的 pro

-- 直接打印普通表的字段
print("normal_tbl.pro1:" .. tostring(normal_tbl.pro1)) -- normal_tbl.pro:1

如果我们打印一个 normal_tbl 不存在的字段

-- 直接打印不存在的字段会得到 nil
print("normal_tbl.pro2:" .. tostring(normal_tbl.pro2)) -- normal_tbl.pro2:nil

如果我们给他加上元表

-- 元表
local mtbl = {
	pro2 = 1
}
-- 普通表
local normal_tbl = { pro1 = 1 }

setmetatable(normal_tbl, mtbl)

再去打印,结果还时nil

print("normal_tbl.pro2:" .. tostring(normal_tbl.pro2)) -- normal_tbl.pro2:nil

如果 normal_tbl 没有 __index 索引字段结构,那么将不会去元表中查找不存在的字段,所以我们需要给,normal_tbl 添加上 __index 索引字段(该字段可以是:table、function,下面示例中使用的是 table)

-- 元表
local mtbl = { pro2 = 1 }
-- 普通表
local normal_tbl = { pro1 = 1 }
setmetatable(normal_tbl, mtbl)

-- 直接打印普通表的字段
print("normal_tbl.pro1:" .. tostring(normal_tbl.pro1)) -- normal_tbl.pro1:1
-- 直接打印不存在的字段会得到 nil
print("normal_tbl.pro2:" .. tostring(normal_tbl.pro2)) -- normal_tbl.pro2:nil

-- 先设置 normal_tbl 元表的__index 后,再打印 pro2
mtbl.__index = mtbl
print("normal_tbl.pro2:" .. tostring(normal_tbl.pro2)) -- normal_tbl.pro2:1

这是可以发现可以将 normal_tbl 中不存在的 pro2 字段打印值为 1 出来了

为何可以酱紫呢?

我们可以看看 lua.org 的文档说明:

__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.

可以看到这么一句 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.

意思是如果 table 的一个 key 不存在该 table 中时,再外部调用这个 key 就会到 table 的元表的 __index 中去查找该 key 字段

还有另一句:The metavalue for this event can be either a function, a table, or any value with an __index metavalue.

意思 __index 可以是一个函数,或是 table 或是任意的值,这里演示了使用 table 的方式

那么接下来演示 使用 function 函数 的方式来设置 __index

function test_metable_idx_in_func()
	-- 元表
	local mtbl = { pro2 = 1, name = "mtbl" }
	-- 普通表
	local normal_tbl = { pro1 = 1, name = "normal_tbl" }
	setmetatable(normal_tbl, mtbl)

	-- 直接打印普通表的字段
	print("normal_tbl.pro1:" .. tostring(normal_tbl.pro1)) -- normal_tbl.pro1:1
	-- 直接打印不存在的字段会得到 nil
	print("normal_tbl.pro2:" .. tostring(normal_tbl.pro2)) -- normal_tbl.pro2:nil

	-- 先设置 normal_tbl 元表的__index 后,再打印 pro2
	mtbl.__index = function(tbl, k)
		-- 在返回 __index 索引的 k 对应名字的字段值之前,我们输出一下打印内容
		print("tbl.name:" .. tbl.name .. " have not the '" .. k .. "' field, so looked up in this metatable value.")
		return mtbl[k]
	end
	print("normal_tbl.pro2:" .. tostring(normal_tbl.pro2)) -- normal_tbl.pro2:1
end

print("test_metable_idx_in_func()")
test_metable_idx_in_func()

__index 为一个参数的时候,参数有两个:第一个是原始查找的 table 对象,第二个是在第一个 table 中查找不到的字段名字字符串,在上面引用的官方文档中对应这么一句:If it is a function, it is called with table and key as arguments

References
  • Metatables and Metamethods
关注
打赏
1688896170
查看更多评论

Jave.Lin

暂无认证

  • 6浏览

    0关注

    546博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0489s