Lua进阶
Lua表深拷贝
Lua的表是一种类似引用类型,这种类型赋值的时候会直接将对象地址赋值过去。
local t10={1,2,3,4,5,6}
local t9=t10
t9[1]=10
print(t10[1]) --- 输出为10
- 递归拷贝
最简单的方式就是新建表,然后遍历要复制的表元素一个个复制过去。由于表本身也可以存表,所以使用递归实现。
function deep_copy(tbl)
local new_tbl = {}
for key, value in pairs(tbl) do
if type(value) == "table" then
new_tbl[key] = deep_copy(value)
else
new_tbl[key] = value
end
end
return new_tbl
end
由于存储的表也有可能是表本身或者是表本身的表元素,所以可能产生循环引用的现象,优化过后的深拷贝函数对已经克隆过后的对象进行了存储。
function clone(object)
local lookup_table = {}
local function _copy(object)
if type(object) ~= "table" then
return object
elseif lookup_table[object] then
return lookup_table[object]
end
local new_table = {}
lookup_table[object] = new_table
for key, value in pairs(object) do
new_table[_copy(key)] = _copy(value)
end
return setmetatable(new_table, getmetatable(object))
end
return _copy(object) -- 返回clone出来的object表指针/地址
end
ipair与pair
- ipair遇到不连续的数据停止输出,遇到nil停止输出,会按照key的顺序输出;而pair会无序输出所有数据。
- ipair和pair都会优先输出没有key的数据。对于pair,同样会无序输出带key的值,但是会按顺序输出不带key的值;对于ipair,在key值方面,他会补充不带key值的key,按顺序输出key。
例子:
local t = {[1]=1,2,[3]=3,4,[5]=5,[6]=6}
print("------ipairs------")
for k,v in ipairs(t1) do
print(k,v)
end
print("——pairs——")
for k,v in pairs(t1) do
print(k,v)
end
结果为:
------ipairs------
1 2
2 4
3 3
------pairs------
1 2
2 4
3 3
5 5
6 6
首先无论pairs还是ipairs都会将无key的元素优先遍历,也就是{2,4}。
此时要注意输出的这个k与实际的key值不是一个值,也就是按顺序开2就是第一个,4就是第二个,所以都直接输出12和24。
之后遍历会沿着2往后找,也就是说在原表内不会再关注1了,而是直接看key=3的键值对,也就是33。
此时再次发生分歧,因为原表中找不到key为4的键值对了。
所以ipairs断开,pairs继续遍历。
理论上从3开始pairs就要随机输出了,但是因为哈希算法排序样本较小,只有三个的话还看不出随机,当数量多了之后就随机了。
lua表中可以用table来表示key
全局变量泛滥
设置_G的元表,在其中进行检测,在触发__ newindex或者__ index时判断元素是否有显式声明过。
典型元方法
_add
处理对象相加,用于重载+
_index
定义表索引,访问不存在的索引时触发_newindex
为不存在的索引赋值时触发_pairs
、_ipairs
定义对象迭代器行为
luaGC与C#GC
unity中的内存管理分为托管内存和非托管内存,GC只影响托管内存。
lua采用增量回收的方式,性能更高。
- lua中需要gc的数据类型——表、用户数据(指用于表示C语言中任意数据的类型)、函数、线程。
lua的gc是基于引用计数,利用标记-清除法来处理循环引用。
lua长短字符串
local shortStr1 = 'This is a short string.'
local shortStr2 = "This is another short string."
local longStr = [[
This is a long string.
It can contain multiple lines
and special characters like \n and \t.
]]
短字符串和string很像,需要转义字符,而长字符串不需要。
长字符串总是存在堆内存中,此外,任何字符串长度超过一定阈值都会存在堆中。