Lua学习笔记--table

Lua只有一种数据结构,叫table。但是他灰常强大,足以满足我们一般的要求,而且可以根据table做出其他的效果。

一.简介

table类型实际上是一种关联数组,是一种具有特殊索引方式的数组,不仅可以通过整数来索引,还可以通过字符串等其他类型(除了nil)来索引。table没有固定大小,可以动态添加元素。
table可以被理解为一个对象,程序使用一个引用来使用table,这个引用是基于引用计数的。如果一个table没有被引用,那么Lua的垃圾回收机制会清除table并回收其内存。
创建table是通过构造式来创建的。
先来看看传统的C语言的方式的数组用法:
--创建一个table,并将其引用使用a保存
a = {}
--向table中添加三条数据
a[1] = "hehe"
a[2] = "haha"
a[3] = "heihei"

--输出
for i = 1,3 do
	print(a[i])
end
结果:
hehe
haha
heihei
请按任意键继续. . .

but Lua的数组的索引可以是其他类型的,类似dictionary的功能。下面是使用字符串作为索引:
--创建一个table,并将其引用使用a保存
a = {}
--table中的索引不仅限于number,使用其他类型的数据也可以作为索引 
a["hehe"] = "heihei"
local i = "hh"
a[i] = "haha"

local t = "hehe"
print(a[t])
print(a["hh"])
结果:
heihei
haha
请按任意键继续. . .


一个非常容易出错的地方:

一种简便的写法:a.name <=>a["name"] 千万不要与a[name]搞混
--创建一个table,并将其引用使用a保存
a = {}
a["name"] = "puppet"
print(a.name)
结果:
puppet

下面的例子更好的看出这个的区别:
a = {}
x = "y"
a[x] = 10
--表示a[x]未定义,为nil
print(a.x)
--表示a["y"],为10
print(a.y)
结果:
nil
10
请按任意键继续. . .

table是匿名的,持有table引用的变量与table自身木有关系。可以有多个变量引用同一个table。当不需要table时,就将这个引用的变量置为nil,当一个table所有的引用都为nil时,那么table就被垃圾回收机制收了。

 a = {}
 a[1] = "haha"
 --b与a引用了同一个table
 b = a
 print(b[1])
 --通过b对table操作等同于通过a对table操作
 b[1] = "heihei"
 print(a[1])

 a = nil
 --b还引用着table
 b = nil
 --现在table被收了
结果:
haha
heihei
请按任意键继续. . .


二.table构造式

构造式是用来初始化table的表达式,是Lua特有的也是灰常有用的一种表达式。
最简单的table构造式就是一个空的table:
a = {}
我们也可以将table构造式用于数组的初始化,比如:
--table构造式
day = {"Sunday", "Monday", "Tuesday", "Wendesday", "Thursday", "Friday", "Saturday"}
--注意,Lua中数组的开始为1,这一点与C等不同
print(day[1])
print(day[4])
结果:
Sunday
Wendesday
请按任意键继续. . .

这里要注意的一点: Lua中数组的起始为1,不是0!!!

对于那种非普通数组的table初始化,lua提供了一种比较简单的方式:
a = {x = "hehe", y = "haha"}

print(a.x)
print(a.y)
结果:
hehe
haha
请按任意键继续. . .

上面的构造式相当于下面的一大串:
a = {}
a.x = "hehe"
a.y = "heihei"

--最麻烦的写法如下:
--a["x"] = "hehe"
--a["y"] = "heihei"

print(a.x)
print(a.y)

这样一看,构造式为我们省去了很多麻烦。另外,还是一定要注意, 构造式里面的x表示的并不是x的值,而是字段"x"!!!即a["x"] = "hehe"


三.table的table

table什么都能装,而且同一个table中可以装不同类型的东东:
a = {x = 1, y = "hehe"}
print(a.x)
print(a.y)
结果:
1
hehe
请按任意键继续. . .

当然,这不是最牛的,最牛的是table的table:
a = {x = "hehe", y = "heihei"}
b = {i = "haha"}
--将key z value b添加到table a中
a.z = b

--使用:a.z表示b,b.i索引到了“haha”
print(a.z.i)
结果:
haha
请按任意键继续. . .


当不需要一个字段时,可以将其赋值为nil:
a = {x = "hehe", y = "heihei"}
--当不需要一个字段时,将其赋值为nil
a.x = nil


四.table的遍历

对于数据结构,遍历是最重要的操作了。

1.数组型遍历

对于数组型的table,遍历比较简单。
a = {"Monday", "Tuesday", "Wednesday"}
--#a是取数组或者线性表最后一个索引值
for i = 1, #a do
	print(a[i])
end
结果:
Monday
Tuesday
Wednesday
请按任意键继续. . .

注意:这里说的数组型table,指的是使用number作为索引的那种C类型的数组。如果索引为其他类型,不能用这种方式来遍历。


2.迭代器遍历

对于那种不是传统数组,而是key-value对的table,就需要使用迭代器进行遍历了。

--一个使用字段索引的table
a = {x = "hehe", y = "haha", z = "heihei"}
--使用迭代器进行迭代,每次i被赋予一个新的key,而k则会被赋值成key所对应的value
for i, k in pairs(a) do
	print(i, k)
end
结果:
y       haha
x       hehe
z       heihei
请按任意键继续. . .

注意,迭代器有几种,在不同的时候需要用不同的迭代器:
用于迭代文件的:io.lines
用于迭代table的:pairs
用于迭代数组元素的:ipairs
用于迭代字符串的单词的:string.gmatch


比如下面用的ipairs迭代传统数组:
a = {"Monday", "Tuesday", "Wednesday"}
--用于迭代传统数组的ipairs迭代器
for i, k in ipairs(a) do
	print(k)
end 
结果:
Monday
Tuesday
Wednesday
请按任意键继续. . .





















你可能感兴趣的:(Lua)