我是靠谱客的博主 体贴飞机,最近开发中收集的这篇文章主要介绍Lua:大小写不敏感引用table键及递归设置元表,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Lua:大小写不敏感引用table键及递归设置元表

Lua中table的键是区分大小写的,即:

local t = {}
t.a = "a"
print(t.A) -- nil

有时候希望可以大小写不敏感地访问、引用table的键,可以通过设置元表实现:

local t = {}
t.a = "a"
t.B = "B"
t.c = "c"

local mt = {}
mt.__index = function(t, k)
	local v
	-- t中含大量键时开销极大
	for tk, tv in pairs(t) do
		-- 大小写不敏感比较键
		if string.lower(tk) == string.lower(k) then
			v = tv
			break
		end
	end
	return v
end

setmetatable(t, mt)

-- 正常调用
print(t.a) -- a
-- 小写转大写调用
print(t.b) -- B
-- 大写转小写调用
print(t.C) -- c

有两个问题:

1.这样的代码仅适用于功能,不适用于性能。

当t中包含的键非常多时,而我们恰好触发原方法__index,就导致一次遍历。

这样做开销极大,在上量跑压力时有很大的问题。(耗费大量CPU做遍历)

2.只针对t有效,t的子孙table,没有设置元表,仍然大小写敏感。

于是我们需要“递归设置元表”。


我这里指的是,将一个元表设置到某个table,以及table中所有的子孙table。

local mt = {}
mt.__index = function(t, k)
	local v
	-- t中含大量键时开销极大
	for tk, tv in pairs(t) do
		-- 大小写不敏感比较键
		if string.lower(tk) == string.lower(k) then
			v = tv
			break
		end
	end
	return v
end

-- 递归设置元表
function recurrence_setmetatable(t, mt)
	if type(t) ~= "table" then
		return
	end

	-- 设置table元表
	setmetatable(t, mt)

	-- 递归table设置子元表
	for _, tv in pairs(t) do
		if type(tv) == "table" then
			recurrence_setmetatable(tv, mt)
		end
	end
end

local t = {}
t.test1024 = {}
t.test1024.test1280 = {}
t.test1024.test1280.key = "value"
t.a = "a"

recurrence_setmetatable(t, mt)

print(t.TEST1024.TEST1280.KEY) -- value
print(t.a) -- a

最后

以上就是体贴飞机为你收集整理的Lua:大小写不敏感引用table键及递归设置元表的全部内容,希望文章能够帮你解决Lua:大小写不敏感引用table键及递归设置元表所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部