Lua进阶

1. ipairs和pairs的区别

使用ipairs遍历时:下标不是数字或者不是递增数字(断了),遍历就会直接结束

使用pairs遍历时:直接不管什么都能遍历,很可靠。


正常情况下遍历,没有任何区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
local tbl1 = { "apple", "pear", "orange", "grape" }
print("=============ipairs的执行结果=============")
for i, v in ipairs(tbl1) do
print(i, '=', v)
end
print("=============pairs的执行结果==============")
for i, v in pairs(tbl1) do
print(i, '=', v)
end

[[
=============ipairs的执行结果=============
1 = apple
2 = pear
3 = orange
4 = grape
=============pairs的执行结果==============
1 = apple
2 = pear
3 = orange
4 = grape
]]

但是只要需要自定义key值就会出现问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
local tbl2 = {}
tbl2[1] = "1"
tbl2[2] = "2"
tbl2[3] = "3"
tbl2[5] = "5"
print("=============ipairs的执行结果=============")
for i, v in ipairs(tbl2) do
print(i, '=', v)
end
print("=============pairs的执行结果=============")
for i, v in pairs(tbl2) do
print(i, '=', v)
end
print('tbl2的长度为:', #tbl2)--长度输出为3,实际上数组中的长度是4


[[
=============ipairs的执行结果=============
1 = 1
2 = 2
3 = 3
从执行结果发现,最后一个元素没有了
=============pairs的执行结果=============
1 = 1
2 = 2
3 = 3
5 = 5
tbl2的长度为: 3
]]

原因:从以上可以发现,其实ipairs会依据key的数值从1开始加1递增遍历相应的table[i]值。 而pairs则能够遍历表中全部的key,而且除了迭代器本身以及遍历表本身还能够返回nil,可是ipairs则不能返回nil,仅仅能返回数字0,遇到nil则循环退出。 它仅仅能遍历到表中出现的第一个不是整数的key.


引申问题:当我们获取 table 的长度的时候无论是使用 # 还是 table.getn 其都会在索引中断的地方停止计数,而导致无法正确取得 table 的长度。

解决方案:使用pairs自己封装

1
2
3
4
5
6
7
function table_len(t)
local len = 0;
for _,v in pairs(t) do
len = len +1
end
return len
end

2. 函数冒号和点的区别

冒号定义函数: 默认会传递self参数

点号定义函数:默认不会传递self参数

self 就是调用者本身

分别定义

1
2
3
4
5
6
7
8
9
10
11
12
13
class = {a = 1}
--冒号定义
function class:test()
--这里会接受self参数
print(self.a)
end
--1
--点号定义
function class1.test1()
--这里不会接受self参数
print(self.a)--会报错

end

调用区别:点号调用冒号 传参数即可,冒号调用 点号是不支持的

1
2
class.test(class)
class1:test1() --报错

3. table表新建值 提示错误 (只可读表)

思路:设置元表 在newindex中做文章

1
2
3
4
local table = setmetatable({},{})
table.key ="key"
table.value = 123
--插入代码
1
2
3
4
5
6
--解决
local mt =getmetatable(table)
function mt:__newindex(key,value)
mt[key] = nil
print("错误,不能修改表")
end