Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4372764
  • 博文数量: 291
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 7924
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-06 14:28
  • 认证徽章:
个人简介

阿里巴巴是个快乐的青年

文章分类

全部博文(291)

文章存档

2018年(21)

2017年(4)

2016年(5)

2015年(17)

2014年(68)

2013年(174)

2012年(2)

分类: Python/Ruby

2013-05-26 23:44:06

        Lua是一种动态类型的语言,在语言中没有类型定义短的语法,每个值都“携带”了其自身的类型信息。在Lua中,有8种基础数据类型:nil(空)、boolean(布尔)、number(数字)、string(字符串)、userdata(自定义类型)、function(函数)、thread(线程)和table(表)。函数type可以根据一个值返回其类型名称:
        print(type(nil))                        -->nil
        print(type(true))                     -->boolean
        print(type(10.4*3))                 -->number
        print(type("hello world"))          -->string
        print(type(print))                     -->function
        type函数总是返回一个字符串,变量没有预定义的类型,因此,任何变量可以包含任何类型的值,函数作为第一类值(first-class value)来看待也可以赋值给某个变量,下面会详细介绍这8中数据类型。

一、nil(空
        nil是一种类型,其只有一个值nil,它的主要功能是用于区别其它任何值。典型的应用是:一个全局变量在第一次赋值前默认值就是nil,将nil赋予一个全局变量就等同于删除它。Lua将nil用于表示一种无效值(non-value)的情况,即没有任何有效值的情况。

二、boolean(布尔
        boolean类型有两个可选值:false和true。Lua将值false和nil视为假,而将除此之外的其它值视为真。
        需要注意的是:Lua在条件测试中,将数字零和空字符串也都视为真,这点不同于某些脚本或者语言。

三、number(数字
        number类型用于表示实数即双精度浮点数。Lua没有整型类型,而用数字来表示32位整数。通过重新编译Lua也可以非常发年底使用其它类型来表示数字,比如:长整型long或单精度浮点数float,这点详见发行版中的luaconf.h文件。数字常量可以是普通写法(4、0.4),也可以使用科学计数法(4.57e-3、0.3e12)。

四、string(字符串
        Lua中的字符串通常表示一个字符序列。Lua完全采用8位编码,Lua字符串中的字符可以具有任何数值编码,包括数值0。也就是说,可以将任意二进制数据存储到一个字符串中。Lua的字符串是不可变的值(immutable values),不能像C语言中那样直接修改字符串的某个字符,而是应该根据修改要求来创建一个新的字符串,比如:
        a = "one string"
        b = string.gsub(a, "one", "another")        --修改字符串的一部分
        print(a)                                                --one string
        print(b)                                                --another string
        Lua的字符串与其它Lua对象(比如:table或函数等)一样,都是自动内存管理机制所管理的对象,即无需担心字符串的分配和释放而由Lua全权处理。一个字符串可以小到只包含一个字母,也可以大到包含整本书,Lua能高效地处理长字符串,在Lua程序中操作100K或1M的字符串是很常见的事情。
        字符串用一对匹配的单引号或双引号来界定,建议在程序中使用相同类型的引号,除非字符串本身包含引号,那么可以使用另一种引号来界定字符串,或者使用反斜杠对引号进行转义,Lua的转义序列类似于C语言。
        还可以用一对匹配的双方括号来界定一个字母字符串,就像写块注释那样。以这种形式书写的字符串可以延伸多行,且Lua不会解释其中的转义序列,如果字符串的第一个字符是换行符,则Lua会忽略它,这种写法对那种含有程序代码的字符串尤为有用,比如:
        page = [[
       
       
        An HTML Page
       
       
        Lua
       
       
        ]]
        write(page)
        有时候字符串中可能包含这样的内容:a=b[c[i]]或者包含已经被注释掉的代码。为了解决这种问题,需要在两个方括号之间加上任意数量的等号,如:[===[,这样字符串只有遇到内嵌有相同数量等号的双右括号时才会结束,即]===],否则Lua会忽略它。通过这种方式,就可以不用对此进行转义了。同理,注释块时也可以采用这种机制,即--[===[开始,]===]结束。
        Lua提供了运行时的数字与字符串的自动转换,即在一个字符串上应用算术操作时,Lua会尝试将这个字符串转换成一个数字,同样,在Lua期望一个字符串但却得到一个数字时,也会将数字转换为字符串:
        print("10" + 1)        -->11       
        print(10 .. 20)         -->1020
        在Lua中,..是字符串连接操作符,当直接在一个数字后面输入它的时候,必须要用一个空格来分隔它们,否则,Lua会将第一个点理解为一个小数点。除此,Lua还提供了数字与字符串之间显示转换的函数,比如:tonumber和tostring。在Lua 5.1中,还可以在字符串前面放置操作符#来获得该字符串的长度:
        a = "hello"
        print(#a)        -->5

五、table(表
        table类型实现了关联数组(associative array)。关联数组是一种具有特殊索引方式的数组,类似于STL中的map。在这里,不仅可以通过整数来索引它,还可以使用字符串或其它类型的值(除了nil)来索引它。table没有固定大小,可以动态地添加任意数量的元素到一个table中。table是Lua中主要的(事实上也是仅有的)数据结构机制,具有强大的功能。基于table,可以以一种简单、统一和高效的方式来表示普通数组、符号表(symbol table)、集合、记录、队列和其它数据结构。Lua也是通过table来表示模块(module)、包(package)和对象(object)的,比如:当输入io.read的时候,其含义是io模块中的read函数,对于Lua而言,这表示使用字符串read作为key来索引table io。
        在Lua中,table既不是值也不是变量,而是对象。可以将一个table想象成一种动态分配的对象,程序仅持有一个对它们的引用或指针,Lua不会暗中产生table副本或创建新的table。table的创建是通过构造表达式完成的,最简单的构造表达式是{}:
        a = {}              --创建一个table,并将它的引用存储到a
        table永远是匿名的,一个持有table的变量与table自身之间没有固定的关联性,当一个程序再也没有对一个table的引用时,Lua的垃圾收集器(garbage collector)最终会删除该table,并复用其内存:
        a["x"] = 10        --新条目,key="x", value=10
        a[20] = "hello"   --新条目,key=20, value="hello"
        b = a                --b与a引用了同一个table
        a = nil               --现在只有b还在引用table
        b = nil               --再也没有对table的引用了,Lua会回收其内存
        与全局变量类似,当table的某个元素没有初始化时,其value为nil,将nil赋予table的某个元素来删除该元素。这种相似性的缘由是因为Lua正是将全局变量存储在一个普通table中。
        Lua对于诸如a["name"]的写法提供了一种更简便的语法糖(syntactic sugar),可以直接输入a.name。需要注意的是:a.x和a[x]不是一回事,前者表示a["x"],表示以字符串"x"来索引table,而后者是以变量x的值来索引table,比如:
        a = {}
        x = "y"
        a[x] = 10        --将10放入字段“y”
        print(a[x])       -->10
        print(a.x)         -->nil
        虽然可以用任何值作为一个table的索引,也可以用任何数字作为数组索引的起始值,但就Lua的习惯而言,数组通常以1作为索引的起始值,这不同于C语言的下标从0开始的习惯。
        长度操作符#用于返回一个数组或线性表的最后一个索引值或其大小,比如:
        --打印a中所有元素
        for i=1, #a do
            print(a[i])
        end
        对于长度操作符Lua中的习惯用法:
        print(a[#a])        --打印列表a的最后一个值
        a[#a] = nil         --删除最后一个值
        a[#a+!] = v       --将v添加到列表末尾
        对于下面数组大小是多少呢:
        a = {}
        a[10000] = 1
        大小是0而不是10000,这是因为数组也是一个table,而table中所有未初始化的元素的索引结果都是nil。Lua将nil作为界定数组结尾的标志,当一个数组有空隙(Hole)时,即中间含有nil时,长度操作符会认为这些nil元素就是结尾标记,因此,应该避免对含有空隙的数组使用长度操作符。当然,可以使用函数table.maxn来返回一个table的最大正索引数:
        print(table.maxn[a])        -->10000

六、function(函数
        在Lua中,函数是作为第一类值来看待的,即函数可以存储在变量中,可以通过参数传递给其它函数,还可以作为其它函数的返回值。这种特性使语言具有了极大的灵活性。
        Lua既可以调用以自身Lua语言编写的函数,又可以调用以C语言编写的函数。Lua所有的标准库都是用C语言写的,标准库中包括对字符串的操作、table的操作、I/O、操作系统的功能调用、数学函数和调试函数。

七、userdata(自定义类型
        由于userdata类型可以将任意的C语言数据存储到Lua变量中,所以这种类型没有太多的预定义操作,只能进行赋值和相等性测试。userdata用于表示一种由应用程序或C语言库所创建的新类型,例如标准的I/O库就用userdata来表示文件。

八、thread(线程
        后面系列会详细分析这种类型,并介绍协程(coroutine)。





阅读(2525) | 评论(1) | 转发(0) |
1

上一篇:Dynamo系统架构

下一篇:Lua之表达式与语句

给主人留下些什么吧!~~

scq2099yt2013-05-26 23:44:38

文明上网,理性发言...

评论热议
请登录后评论。

登录 注册