这章我们来了解lua中变量的基本类型。
Lua中一共有8种基础类型:
nil(空)、boolean(布尔)、number(数字)、string(字符串)、userdata(自定义类型)、function(函数)、thread(线程)和 table(表)。
不过这篇暂时不对userdata和thread进行介绍,后面文章我们会详细介绍这两种类型的。
首先看这段代码:
type函数可以返回参数的类型,返回值为string类型。
首先需要说明的一点是:
和C\C++,Java这类语言的语法不同的是,变量没有预定义的类型,任何变量都可以包含任何类型的值。其类型可以随时根据赋值语句中右值类型改变而改变。
可以看出来全局变量a根据赋值语句随时改变类型。是不是语法很随性呢?
1.nil(空)
nil是一种类型,它也只有一个值nil,它的主要功能是用于区别其他任何值。就像之前所说的,一个全局变量在第一次赋值之前的默认值就是nil,如果将一个变量的值赋为nil,其作用等同于删除它。
2.boolean(布尔)
和其他大多数语言一样,布尔变量只有两个值:true 和 false . 其意义和其他语言相似,分别表示逻辑真和逻辑假。在Lua中任何值都可以表示一个条件(也就是可以转化为boolean变量)。只有false和nil被视为假。其他都视为真。(注意:0变量也会被视为真,这是和C语言有区别的)
3.string(字符串)
lua的string采用八位编码,lua字符串中的字符可以具有任何数值编码,包括数值0。也就是说,可以将任意二进制数据存储到一个字符串中。
lua的字符串是不可变的值。不能像在C语言中那样对一个字符串中的某个字符进行修改。不过可以根据修改创建一个新的字符串。
如下:
值得注意的是:和C语言一样,字面型字符串中可以使用转义字符表示特殊含义的符号:比如换行、双引号等。
不过,如果我想书写一段含有这类特殊符号比较多的字符串(比如字符串描述的是一段代码),岂不是每个字符前都要加转义字符?
其实不用,lua对于这种情况设计了特殊的语法。
说了这么多字符串基本语法,忘了介绍常用的字符串操作。
我们可以用 .. 来连接两个字符串。
如果操作数为number会自动转化为字符串。所以可以通过将number跟一个空串连接将该数字转化为字符串。同样也可以使用函数tonumber()将字符串转化为number。值得注意的是,如果这个字符串内容不能表示一个正确的数字时,tonumber返回一个nil。
使用#后接一个字符串可以返回这个字符串的长度。
#"this is length of string" 的值为 24
OK,字符串的基础内容就讲到这里,关于字符串相关函数详细内容留到后面字符串函数库再举例介绍吧。
4.number(实数)
lua中数值类型变量是不分实数和整数的,也就是说既可以为整数也可以为实数。当然你也可以把整数看做是小数部分为0的实数。lua中number类型的变量其实默认就是C语言中的double类型。当然也可以通过修改 luaconf.h使得number对应C语言中__int64或者其他的数值类型。
5.function(函数)
在lua中函数是作为"第一类值",也就是说函数作为一个类型,可以存储在变量之中。可以通过参数传递给其他函数也可以作为其他函数的返回值。
在以上代码的1、2两段代码是等效的。
在这里我只是简单介绍一下Lua中函数的基本概念。lua函数的函数其他用法和其他语言是比较相似的。至于在lua中函数的多值返回、闭包(closure)特性等后面函数专门章节会有介绍。
6.table(表)
table(表)是Lua中最为灵活的一个数据类型。实现了"关联数组","关联数组"是一种具有特殊索引方式的数组。不仅可以通过整数来索引它,还可以使用字符串或其他类型的值(除了nil)来索引它。此外,table没有固定的大小,还可以动态地添加任意数量的元素到一个table中。所以通过table这个数据类型,我们可以实现普通数组,符号表,集合,记录,队列,栈和其他数据结构。
好,介绍的废话说的太多了,下面我来介绍table使用的语法:
通过 { } 两个空大括号可以构造一个空的table表。然后可以通过中括号key-value的方式添加,更新,删除table表里面的内容。
Lua为了使得语法更加类似于面向对象的语法,所以Lua对于诸如a["name"]的写法提供了一种更简洁的语法糖,可以直接输入a.name。所以以上代码可以改为:
但是值得注意的是:以上语法必须满足作为key的string必须满足变量的命名也就是以字母或者下划线开头只含有字母下划线数字的字符串。
如何用table模拟普通数组呢?看下面的代码吧:
当a作为普通数组时,#a返回的是数组的大小。值得注意的是:lua中数组起点为1,而不是0。这是跟许多语言的规定是不同的。
但是思考一下:因为table中没有添加的key默认的value是nil。那么Lua是以nil作为界定数组结尾的标志。当一个数组有空隙,也就是中间含有nil的时候呢?#a就变得不可控了。尽管在正常使用中不会出现这样的情况,所以使用#a是安全的。如果真的需要处理那些含有"空隙"的数组,可以使用函数table.maxn.它将返回一个table的最大正索引数:
table的基本语法就介绍到这里,下面给出一个由table类型实现链表结构:
其中涉及到的table { } 构造语法就留到后面table专章介绍了。
好了,Lua的基本数据类型都简单介绍完了。下节我们介绍Lua的赋值语句、控制语句