0%

lua进阶

Lua进阶

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很像,需要转义字符,而长字符串不需要。

长字符串总是存在堆内存中,此外,任何字符串长度超过一定阈值都会存在堆中。