魔兽世界编程宝典(4-1)

 

第4章             使用表
4.1        用表来存储数据
在Lua中,表是用来存储其他变量(通常这些变量都是相互关联的)的实体。它是成对元素的一个集合,每一对元素都由一个关键字和一个值组成,在表中,我们可以使用这个关键字来获得与它唯一对应的值。
4.1.1 创建和索引表
下面的代码新建了一个表:
> alice={}
在Lua中,表达式{}可以新建一个表,这里创建的是一个空表。alice是这个表的名称,我们可以用如下的语句为这个表赋值:
> alice["name"]="艾丽斯"
> alice["phone"]="13883838438"
> alice["address"]="三八胡同38号"
> alice["city"]="暴风城"
> alice["state"]="FS"
这里的每一行都在告诉Lua,可以通过中括号里的关键词来获得某个值:
> print(alice["name"])
艾丽斯
> print(alice["address"])
三八胡同38号
中括号里的关键字可以是除nil之外的任意字符( 默然说话:经测试,可以使用中文字符,不过,由于Lua的编译器似乎对中文字符的支持不是太好,还是尽量避免使用吧)。这样一来,我们也可以使用数字来作为关键字:
> alice[1]="测试数据"
> alice[2]=12
> print(alice[1])
测试数据
> print(alice[2])
12
4.1.2 从表中清除元素
如果你使用一个在表中不存在的关键字时,表将返回一个nil。看例子:
> print(alice["fax"])
nil
所以我们可以利用这一点,来完成对于值的清除:只要简单的赋值为nil就可以了。
> alice[1]=nil
> alice[2]=nil
> print(alice[1])
nil
4.1.3 字符串关键字的快捷方式
如果你的关键字是一个字符串而不是一个数字,Lua提供了一种更加简单的方法来使用它,例如,原来是这样写的:
> alice["name"]="艾丽斯"
现在你也可以这样写:
> alice.name="艾丽斯"
同样,你也可以使用点的形式来访问表中的值:
> print(alice.name)
艾丽斯
> print(alice.address)
三八胡同38号
不过相对于没有任何命名要求的中括号的形式来说,点的这种形式对关键字的命名是有要求,它们必须以字母或下划线开头,并且整个关键字只能包括字母、数字和下划线。中文字符,Lua的保留关键字符(如for,do,end等)都不能使用。所以alice[“姓名”]是正确的,但alice.姓名却是不正确的。
4.1.4 创建有内容的表
上面介绍的创建无内容的表,然后再给它键-值对的方式在实际使用中显示有些罗嗦,下面这种形式大家一定会更喜欢:
> alice={
>> ["name"]="艾丽斯",
>> ["address"]="三八胡同38号",
>> ["state"]="FS",
>> }
类似于前面讲的点引用方式,上面的代码还可以更简单( 默然说话:当然,命名也就有要求了!
> alice={
>> name="艾丽斯",
>> address="三八胡同38号",
>> state="FS",
>> }
大家要注意两种写法在语法格式上的相同点和不同点。相同点就是在每一个键—值对之间都有一个逗号分隔,最后一个键—值对的逗号可以打,也可以不打( 默然说话:不过最好是打上,方便将来添加新的键 --值对),不同之处就是一个要打中括号和双引号,另一个不用打中括号和双引号。
4.2        把表当作数组使用
其实如果您学习过其他编程语言,在前面应该就有感觉。当Lua中的表使用了数字作为关键字时,它就和其他许多编程语言中的数组是很相似的。Lua把使用从1开始的连续整数作为关键字的表就称为数组。
4.2.1 创建数组
你可以这样创建一个数组:
array1={
       值1,
       值2,
       值3,
       ……
}
也可以这样创建一个数组:
array1={
       [1]=值1,
       [2]=值2,
       [3]=值3,
       ……
}
所以我们说,数组是表的一种特殊形式。
4.2.2 获取数组的长度
第2章介绍过一个获取字符串长度的标识符(#),这个符号对于数组同样适用:
> tbl={"a","b","c"}
> print(#tbl)
3
这个长度的最大用处就是在于遍历时能够提供一个动态的下标:
> for i=1,#tbl do
>> print(tbl[i])
>> end
a
b
c
默然说话:这里对#的使用是有限制的,也就是说,这个伪装成数组的表,它的下标必须是从1开始的,而且必须是连续的。这样,#得到的长度才是可靠的。
4.2.3 在数组中添加元素
向数组中添加元素可以这样很简单的写成:
> tbl[#tbl+1]="a"
但这样的代码很难读懂,所以Lua提供了一个标准的table.insert()函数,可以让添加数组元素变得简单易懂。table.insert()的语法是:
table.insert(数组,[下标,]值)
参数的意义如下:
数组——将被增加元素的数组
下标——增加的元素所在的位置
值——这个元素的值
第二个参数打了中括号,意思表明这个参数是可以省略的,如果你省略了它,这个值就会被添加到数组的末尾。
我们还是具体用一个示例来说明一下,首先我们作点准备工作,声明一个数组,包括三个默认的字符串:
> tmp={"苹果","香蕉","梨"}
由于后面我们要反复显示这个数组里的所有内容,所以我们再定义一个函数,它用于显示一个数组中的全部内容:
> print_tmp=function()
>>     for i=1,#tmp do
>>         print(i,tmp[i])
>>     end
>> end
先显示一下当前内容:
> print_tmp()
1       苹果
2       香蕉
3      
之后,我们调用table.insert(),为这个数组再添加两个水果试试。
> table.insert(tmp,"芒果")
> table.insert(tmp,"桔子")
> print_tmp()
1       苹果
2       香蕉
3      
4       芒果
5       桔子
大家看到,我们使用了省略第二个参数的形式,所以,新加入的两个水果被在放了末尾,我们再来试试有三个参数的形式:
> table.insert(tmp,3,"无花果")
> print_tmp()
1       苹果
2       香蕉
3       无花果
4      
5       芒果
6       桔子
大家看到,无花果出现在了3的位置上,其他的水果都依次被移动了位置,并重新进行了编号。
4.2.4 从数组中删除元素
Lua提供了一个与table.insert()类似的函数table.remove()来执行删除元素的操作,它的语法如下:
值=table.remove(数组[,下标])
这个函数有两个参数
数组——将被删除元素的数组
下标——被删除元素所在的位置
同样,这个下标也是可以省略的,如果省略了,表示删除数组中最后一个元素
这个函数还有一个返回值,它就是那个被删除的元素值。
来试试,接上面的例子,我们首先使用一个参数的形式:
> table.remove(tmp)
> print_tmp()
1       苹果
2       香蕉
3       无花果f
4      
5       芒果
我们看到最后一个元素桔子被删除了。接下来,再试试两个参数的形式:
> table.remove(tmp,3)
> print_tmp()
1       苹果
2       香蕉
3      
4       芒果
大家可以看到,无花果被删除了,但数组也及时进行了调整,它们的位置被重新进行了编号。
4.2.5 对数组中的元素排序
如果数组的元素包括的是可以进行比较的元素时,有一个标准的库函数table.sort()可以对它们进行排序。它的语法是:
table.sort(数组[, 排序规则])
table.sort()的第二个参数我们将在第5章详细介绍,而第一个参数就是您需要排序的数组。
我们还是来看个例子吧。由于前面的数组我们使用了汉字,而Lua对汉字的排序不是按我们的理解来进行的( 默然说话:平常我们都是根据汉语拼音的英文排序或者是笔画数的多少进行排序的,但 Lua并未采用这两种方式,它似乎只是简单比较了汉字的编码大小。这就让我们很难理解了),所以我们重新声明一个数组,并乱序初始化几个英文字符:
> tmp={"b","c","a","e","d"}
先来打印一下:
> print_tmp()
1       b
2       c
3       a
4       e
5       d
大家看到,是没有排序的。现在,来排序一下,然后再打印:
> table.sort(tmp)
> print_tmp()
1       a
2       b
3       c
4       d
5       e
数组中的英文字符已经按字母顺序进行了排序,整个数组里,所有元素的位置顺序也被进行了调整。
4.3        用名称空间使用表
前面介绍了几个对数组进行处理的函数:
table.insert()
table.remove()
table.sort()
从这一组函数的名称上我们可以看出一个规律:它们都是以table.开头的,这个table在这里我们就称它为名称空间。名称空间提供了一种对于相关函数的管理方式,它增加了我们对大量函数的管理能力。在Lua中,这种名称空间其实就是一个表,所以上面的函数我们也可以使下面的形式进行调用:
table[“insert”]()
table[“remove”]()
table[“sort”]()
下面我们就来学习如何创建名称空间,换句话说,如何创建我们自己的函数库。
4.3.1 创建util名称空间
创建一个名称空间和创建一个表没什么区别:
> util={}
4.3.2 向util中添加函数
向名称空间添加函数有两种方法,如果你的函数已经定义好了,你可以直接将函数与一个键关联起来。如果你的函数还没有定义好,那你可以直接将函数定义赋值给一个键,下面举例说明:
1. 存储已有的函数
还记得我们前面写的温度转换函数么?如果你关闭过Lua编译器,那么把它再重新写一遍:
> convert_c2f=function(celsius)
>> return (celsius*1.8)+32
>> end
好了,这个函数现在已经存在于Lua编译器中了,接下来,我们把它赋值给util名称空间:
> util.c2f=convert_c2f
现在,我们就可以使用util.c2f()的形式调用这个函数了,和你直接使用函数名convert_c2f是一样的效果:
> print(util.c2f(0))
32
2. 定义新函数
其实你完全可以不用去绕个弯子,你可以直接将函数的定义赋值给一个名称空间的。下面是我们前面写过的阶乘函数,我们直接赋值给了util名称空间:
> util.factorial=function(num)
>>     local total=1
>>     for i=1,num do
>>         total=total*i
>>     end
>>     return total
>> end
上面的这种写法,是我们在创建自己的函数库时最常用的写法。它的调用方式如下:
> print(util.factorial(5))
120

你可能感兴趣的:(默然说话,编程,lua,编译器,function,测试,存储)