• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Lua教程(二):基础知识、类型与值介绍

    一、基础知识:

    1. 第一个程序和函数:
        在目前这个学习阶段,运行Lua程序最好的方式就是通过Lua自带的解释器程序,如:
     

    复制代码 代码如下:

        /> lua
        > print("Hello World")
        Hello World
     

        这样我们就可以以交互性的方式输入lua代码,并立即得到执行结果了。对于代码块较少的测试程序来说,这种方式确实是非常方便的,然而对于相对复杂的程序而言,这种方式就不是很合适了。如果是这样,我们可以将Lua代码保存到一个独立的Lua程序文件中,之后再通过Lua解释器程序以命令行参数的形式执行文件中的Lua代码。如我们将下面的Lua代码保存到test.lua的文件中:

    复制代码 代码如下:

    function fact(n)
        if n == 0 then
            return 1
        else
            return n * fact(n - 1)
        end
    end
    print("Enter a number:")
    a = io.read("*number")
    print(fact(a))

    复制代码 代码如下:

    /> lua D:/test.lua
        Enter a number:
        4
        24

    2. 代码规范:

        1). Lua的多条语句之间并不要求任何分隔符,如C语言的分号(;),其中换行符也同样不能起到语句分隔的作用。因此下面的写法均是合法的。如:
     

    复制代码 代码如下:

     a = 1
    b = a * 2
       
    a = 1;
    b = a * 2;
       
    a = 1; b = a * 2;
    a = 1  b = a * 2
     

        2). 通过dofile()方法引用其他Lua文件中的函数,如:

    复制代码 代码如下:

    function fact(n)
        if n == 0 then
            return 1
        else
            return n * fact(n - 1)
        end
    end

    将上面的函数保存到test2.lua文件中。

    复制代码 代码如下:

        /> lua
        > dofile("d:/test2.lua")
        > print(fact(4))
        24

        3). 词法规范。
        和大多数其它语言一样,在声明变量时,变量名可以由任意字母、数字和下划线构成,但是不能以数字开头。在Lua中还有一个特殊的规则,即以下划线(_)开头,后面紧随多个大写字母(_VERSION),这些变量一般被Lua保留并用于特殊用途,因此我们在声明变量时需要尽量避免这样的声明方式,以免给后期的维护带来不必要的麻烦。
        Lua是大小写敏感的,因此对于一些Lua保留关键字的使用要特别小心,如and。但是And和AND则不是Lua的保留字。
        4). Lua中的注释分为两种,一种是单行注释,如:
     
    复制代码 代码如下:

        --This is a single line comment.
        另外一种是多行注释,如:
        --[[
        This is a multi-lines comment.
        --]]

        3. 全局变量:
        在Lua中全局变量不需要声明,直接赋值即可。如果直接访问未初始化的全局变量,Lua也不会报错,直接返回nil。如果不想再使用该全局变量,可直接将其置为nil。如:
     
    复制代码 代码如下:

        /> lua
        > print(b)
        nil
        > b = 10
        > print(b)
        10
        > b = nil
        > print(b)
        nil
       

        4. 解释器程序:
        命令行用法如下:
        lua [options] [lua-script [arguments] ]
        该工具的命令行选项主要有以下3个:
        -e: 可以直接执行命令行中Lua代码,如:lua -e "print(\"Hello World\")"
        -l: 加载该选项后的Lua库文件,如:lua -l mylib -e "x = 10",该命令在执行之前先将mylib中的Lua代码加载到内存中,在后面的命令中就可以直接使用该文件中定义的Lua函数了。
        -i: 在执行完指定的Lua程序文件之后,并不退出解释器程序,而是直接进入该程序的交互模式。   
        在解释器程序的交互模式下,我们可以通过在表达式前加等号(=)标识符的方式直接输出表达式的执行结果。通过该方式,我们可以将该程序用于计算器,如:
       
    复制代码 代码如下:

     /> lua
        > = 3 + 1 + 4
        8
     

        该小节最后需要介绍的是lua脚本的命令行参数访问规则。如:
     
    复制代码 代码如下:

        /> lua lua-script.lua a b c
     

        在该脚本的程序入口,lua解释器会将所有命令行参数创建一个名为arg的table。其中脚本名(lua-script.lua)位于table索引的0位置上。它的第一个参数(a)则位于索引1,其它的参数以此类推。这种索引方式和C语言中读取命令行参数的规则相同。但是不同的是,Lua提供了负数索引,用以访问脚本名称之前的命令行参数,如:
     
    复制代码 代码如下:

        arg[-1] = lua
        arg[0] = lua-script.lua
        arg[1] = a
        arg[2] = b
        arg[3] = c

    二、类型与值:

        Lua是一种动态类型的语言。其语言本身没有提供类型定义的语法,每个值都“携带”了它自身的类型信息。在Lua中有8中基础类型,分别是:nil、boolean、number、string、userdata、function、thread和table。我们可以通过type函数获得变量的类型信息,该类型信息将以字符串的形式返回。如:
     

    复制代码 代码如下:

        > print(type("hello world"))
        string
        > print(type(10.4))
        number
        > print(type(print))
        function
        > print(type(true))
        boolean
        > print(type(nil))
        nil
        > print(type(type(X)))
        string

        1. nil(空):
        nil是一种类型,它只有一个值nil,它的主要功能是由于区别其他任何值。就像之前所说的,一个全局变量在第一次赋值前的默认值的默认值就是nil,将nil赋予一个全局变量等同于删除它。Lua将nil用于表示一种“无效值”的情况。
        
        2. boolean(布尔):
        该类型有两个可选值:false和true。在Lua中只有当值是false和nil时才视为“假”,其它值均视为真,如数字零和空字符串,这一点和C语言是不同的。
        
        3. number(数字):
        Lua中的number用于表示实数。Lua中没有专门的类型表示整数。
        
        4. string(字符串):
        Lua中的字符串通常表示“一个字符序列”。字符串类型的变量是不可变的,因此不能像C语言中那样直接修改字符串的某一个字符,而是在修改的同时创建了新的字符串。如:
    复制代码 代码如下:

    1 a = "one string"
    2 b = string.gsub(a,"one","another")
    3 print(a)
    4 print(b)
        /> lua d:/test.lua   
        one string
        anotner string
     

        Lua支持和C语言类似的字符转义序列,见下表:

    在Lua中还可以通过[[ all strings ]]的方式来禁用[[ ]]中转义字符,如:
        page = [[ html> head> title> An Html Page /title> /head> ]]
        如果两个方括号中包含这样的内容:a = b[c[i]],这样将会导致Lua的误解析,因此在这种情况下,我们可以将其改为[===[ 和 ]===]的形式,从而避免了误解析的发生。
        Lua提供了运行时的数字与字符串的自动转换。如:
     

    复制代码 代码如下:

        > print("10" + 1)
        11
        > print("10 + 1")
        10 + 1
     

        如果在实际编程中,不希望两个数字字符串被自动转换,而是实现字符串之间的连接,可以通过" .. "操作符来完成。如:
     
    复制代码 代码如下:

        > print(10 .. 20)
        1020
     

        注意..和两边的数字之间必须留有空格,否则就会被Lua误解析为小数点儿。
        尽管Lua提供了这种自动转换的功能,为了避免一些不可预测的行为发生,特别是因为Lua版本升级而导致的行为不一致现象。鉴于此,还是应该尽可能使用显示的转换,如字符串转数字的函数tonumber(),或者是数字转字符串的函数tostring()。对于前者,如果函数参数不能转换为数字,该函数返回nil。如:
    复制代码 代码如下:

    line = io.read()
    n = tonumber(line)
    if n == nil then
        error(line .. " is not a valid number")
    else
        print(n * 2)
    end

    关于Lua的字符串最后需要介绍的是"#"标识符,该标识符在字符串变量的前面将返回其后字符串的长度,如:

    复制代码 代码如下:

    1 a = "hello"
    2 print(#a)
        /> lua d:/test.lua
        5
            
        5. table(表):

        我们可以将Lua中table类型视为“关联数组”,如C++标准库中的map,差别是Lua中table的键(key)可以为任意类型(nil除外),而map中的键只能为模参类型。此外,table没有固定的大小,可以动态的添加任意数量的元素到一个table中。table是Lua中最主要数据结构,其功能非常强大,可用于实现数组、集合、记录和队列数据结构。以下为table的变量声明,以及关联数据的初始化方式:

    复制代码 代码如下:

    a = {}              -- 创建一个table对象,并将它的引用存储到a
    k = "x"
    a[k] = 10           -- 创建了新条目,key = "x", value = 10
    a[20] = "great"     -- 新条目,key = 20, value = "great"
    print(a["x"])
    k = 20
    print(a[k])         -- 打印great
    a["x"] = a["x"] + 1
    print(a["x"])       -- 打印11

        所有的table都可以用不同类型的索引来访问value,当需要容纳新条目时,table会自动增长。

    复制代码 代码如下:

    a = {}
    for i = 1, 100 do
        a[i] = i * 2
    end
    print(a[9])
    a["x"] = 10
    print(a["x"])
    print(a["y"])      --table中的变量和全局变量一样,没有赋值之前均为nil。

    --输出结果为
    --18
    --10
    --nil

       在Lua中还提供了另外一种方法用于访问table中的值,见如下示例:

    复制代码 代码如下:

    a.x = 10      --等同于a["x"] = 10
    print(a.x)    --等同于print(a["x"])
    print(a.y)    --等同于print(a["y"])

        对于Lua来说,这两种方式是等价的。但是对于开发者而言,点的写法隐式的将table表示为记录,既C语言中的结构体。而之前讲述的字符串表示法则意味着任何字符串均可作为table的key。
        如果需要将table表示为传统的数组,只需将整数作为table的key即可。如:
    复制代码 代码如下:

    a = {}
    for i = 1,10 do
        a[i] = i * 2
    end

    for i = 1,10 do
        print(a[i])
    end


        在Lua中,我通常习惯以1作为数组索引的起始值。而且还有不少内部机制依赖于这个惯例。如:
    复制代码 代码如下:

    a = {}
    for i = 1,10 do
        a[i] = i * 2
    end

    for i = 1,#a do
        print(a[i])
    end

    由于数组实际上仍为一个table,所以对于数组大小的计算需要留意某些特殊的场景,如:

    复制代码 代码如下:

        a = {}
        a[1000] = 1

        在上面的示例中,数组a中索引值为1--999的元素的值均为nil。而Lua则将nil作为界定数据结尾的标志。当一个数组含有“空隙”时,即中间含有nil值,长度操作符#会认为这些nil元素就是结尾标志。当然这肯定不是我们想要的结果。因此对于这些含有“空隙”的数组,我们可以通过函数table.maxn()返回table的最大正数索引值。如:
    复制代码 代码如下:

    a = {}
    a[1000] = 1
    print(table.maxn(a))   
     
    -- 输出1000

        6. function(函数):
        在Lua中,函数可以存储在变量中,可以通过参数传递其它函数,还可以作为其它函数的返回值。这种特性使语言具有了极大的灵活性。

        7. userdata(自定义类型):
        由于userdata类型可以将任意C语言数据存储到Lua变量中。在Lua中,这种类型没有太多预定义的操作,只能进行赋值和相等性测试。userdata用于表示一种由应用程序或C语言库所创建的新类型。

    您可能感兴趣的文章:
    • Lua实现split函数
    • C调用lua函数需要考虑的问题
    • Lua中if语句嵌套的使用教程
    上一篇:Lua教程(一):简介、优势和应用场景介绍
    下一篇:Lua教程(三):表达式和语句
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Lua教程(二):基础知识、类型与值介绍 Lua,教程,二,基础知识,类型,