4.表

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_25327609/article/details/85699655

表是一种动态分配的对象,只能操作指向表的引用,除此之外Lua语言不会进行隐藏的拷贝和创建新的表。

a= {}
k="x"
a[k]=10
a[20]=100
print(a[20])
--表永远是匿名的1,表本身与保存表的变量之间没有固定的关系
b=a
b["x"]=200
print(a["x"])
-- 当不再有引用指向表时,垃圾回收机制会删除这个表,并重新利用其占用的内存。
b=nil
a=nil

--输出
100
200

表索引

表可以使用不同类型的值作为索引。

a={}
a[10]=10
a["x"]=5
--未初始化的值为nil ,将nil赋值给表元素即可将其删除。
print(a["y"])
print(a["x"])
a["x"]=nil
print(a["x"])

当把表作为结构体使用时,有两种形式访问表元素,一般的字符串索引形式和点分形式。
点分形式:可以把索引当做成员名称使用(a.name等价于a[“name”])

a={}
a.x=10  --等价于 a["x"]=10
print(a.x)
print(a.y)
--输出
10
nil

一般用a.x点分形式说明表被当做结构体使用,此时表由固定,预先定义的键组成的集合,而字符串索引形式a[“x”]是表的一般用法
:a.x 等价于a[“x”] 不等于a[x].
整型和浮点类型的索引时,2与2.0的值相同,他们作为索引时指向同一个元素。

a={}
a[2.0]=10
a[2.1]=100
print(a[2])
print(a[2.1])
--输出
10
100

当被用作表索引时,能够转换为整型的浮点数都会被转化为整型,即2.0可以,而2.1不行。

表构造器

用来创建和初始化表的表达式。

--1.最简单的空构造器
a={}
--2.初始化列表形式(则b[1]="A",注意从1开始)
b={"A","B","C","D"}
print(b[4])
--3.初始化记录式
c={x=10,y=20} --等价于c={}; c.x=10;a.y=20 前者速度更快
print(c["x"])
--输出
D
10

在同一个构造器中,可以混用记录式和列表式写法:

line ={
	clolor="red",
	thickness=2,
	npoints=4,
	{x=0,y=1}, --line[1]
	{x=1,y=1}, --line[2]
	{x=3,y=1}, --line[3]
	{x=4,y=1} --line[4]
}
--同时,也展示了表嵌套的用法
print(line[1].x)
print(line[1]["y"])
--输出
0
1

这两种构造方式的局限性:列表式不能使用负数索引(从1开始),记录式只能使用符合标识符规范的标识符。

m={_a=12} 
m={_2=12} 
m={a=12} 
-- m={2=12} 不符合标识符规范

对此,可以使用更加通用的构造器,即通过方括号括起来的表达式显式指定每一个索引。

a={["+"]="add",["-"]="sub"}
print(a["+"])

i=-10
s="-"
b={[i+0]=s,[i+1]=s..s,[i+2]=s..s..s}
print(b[-8])

c={x=0,y=0}--等价于{["x"]=0,["y"]=0}
d={"r","g","b"}--等价于{[1]="r",[2]="g",[3]="b"}
--输出
add
---

数组(列表)和序列

表只要使用整型作为索引,即可作为常见的数组,一般Lua中惯例是从1开始。序列是指由指定n个正整数值类型的键所组成集合{1,…n}形成的表。特别地,不包含数值类型索的表的长度为0的序列。同样使用#获取序列长度。

a={"1","2","3","4"}
print(#a)
b={}
b[1]=1
b[2]=2
print(#b)
c={}
c[2]=2
c[3]=3
print(#c)
--对于存在空洞(nil),长度操作符不可靠 这种情况下 应该存储在一个非数值键字段中,如c["n"]
d={}
d[1]=1
d[2]=2
d[4]=4
d[5]=5
print(#d)
e={}
e[1]=1
e[2]=2
e.age=4
e.name="XXX"
print(#e)
--输出
4
2
0
5
2

遍历表

--1.使用pairs遍历一般的表,但每次遍历顺序不确定
t1={10,"abc",x=11,y=12}
for k,v in pairs(t1) do
	print(k,v)
end
--2.使用ipairs遍历序列(即不存在空洞(nil)的数组)
print(".......................")
t2={"abc",2.5,4}
for k,v in ipairs(t2) do 
	print(k,v)
end
--非序列 即不是从1..n的键,不能这样遍历,只会遍历从1开始有序的部分
print(".......................")
t3={"abc",2.5,[4]=4}
for k,v in ipairs(t2) do 
	print(k,v)
end
--3.序列的第二种遍历方式
print(".......................")
t4={10,20,"abc",2.5}
for k=1,#t4 do
	print(t4[k])
end
--输出
1	10
2	abc
y	12
x	11
.......................
1	abc
2	2.5
3	4
.......................
1	abc
2	2.5
3	4
.......................
10
20
abc
2.5

安全访问

当不确定是否存在某个库,以及某个库中是否存在某个函数可能需要如下写法:

--是否存在函数时
if  lib.foo then..
--是否存在库,以及是否存在函数
if lib and lib.foo then..

当很长时很麻烦,采用:

--利用lua or性质,以及表中不存在某个键时返回nil
zip =(((company or {}).director or {}).adress or {}).zipcode
--进一步简化
E={}
zip =(((company or E).director or E).adress or E).zipcode

表标准库

用于操作序列(书里面列表和序列概念较为混乱)

  1. table.insert(t,[index,]value) :向序列t的指定位置index插入一个元素value,其他元素依次后移,不指定位置时,插入到最后。
  2. table.remove(t[,index]) :删除并返回序列指定位置的元素,然后将其后的元素移动填充删除元素后造成的空洞。若不指定位置则删除最后一个元素。
  3. table.move(t,start,end,index,[another table]):将表t中从索引start开始到end的元素,移动(或者说复制,因为原位置并未删除)到位置another table的位置index上。未指定another table则在原表上移动。
a={1,2,3}
print("..........")
for k,v in ipairs(a) do
	print(k,v)
end
--insert
table.insert(a,2,5)
print("..........")
for k,v in ipairs(a) do
	print(k,v)
end
--remove
table.remove(a,2)
print("..........")
for k,v in ipairs(a) do
	print(k,v)
end

--move 带参数
t={}
table.move(a,2,3,1,t)
print("..........")
for k,v in ipairs(t) do
	print(k,v)
end
--move 不带参数
t={}
table.move(a,2,3,1)
print("..........")
for k,v in ipairs(a) do
	print(k,v)
end
--显然此是复制效果,所以a[3]还在,所以如果要删除则主动
--a[3]=nil
--输出
..........
1	1
2	2
3	3
..........
1	1
2	5
3	2
4	3
..........
1	1
2	2
3	3
..........
1	2
2	3
..........
1	2
2	3
3	3

猜你喜欢

转载自blog.csdn.net/qq_25327609/article/details/85699655
今日推荐