Lua(1) ——基础语法

    xiaoxiao2021-03-25  226

    唠叨】

        首先,我已经默认你已经学过至少一门宿主语言了(C++、Java等),然后转向学习Lua。

        因为51cto中对于Lua语言没有代码高亮,为了让代码看起来丰富多彩,我只好用截图了。

        本节内容仅介绍Lua的简单基础语法,更多用法请百度:Lua中文教程 、 Lua参考手册 。

        基于Lua 5.1。

    【学习感慨】

        > 语句末尾不需要加分号 ; 

        > 语句块不是用花括号 { } , 而是 do 语句块 end 表示语句块的开始和结束。

            而 花括号 {} 表示的为一个 表结构 。

        > 运算符 ^  :表示幂运算。(即 2^10 = 1024)

        > 不等于号为: ~=

        > 变量的定义不需要加数据类型。直接 a = 10。

        > 且(and)、或(or)的运算返回值不是true/false而是运算符左边或右边的变量值

        > 除了 nilfalse ,其余的均为真。( 0 和 空串"" 也为真)。

        > 变量的赋值可以多个一起赋值。( a,b,c = 10,20,30 )。

        > 函数可以返回多个值。( return a,b,c

        > Lua中数据结构类型只有唯一的一个:表(table)

            它既可以表示一个数组,也可以是一个数据结构,或者是一个类。

        > 数组下标从 1 开始,而不是 0 。

    【致谢】

        《Programming in Lua》中文版 , 翻译由 www.luachina.net 完成。


    0、Lua环境配置

        可以去lua官网 www.lua.org  下载资源文件,然后在文本编辑器来编写。

        也可以使用 eclipse ,下载 ldt 插件,就可以在 eclipse 中编写Lua的代码了。

    0、Lua的一个例子

        先来看看Lua的一个例子,图个新鲜。

        注:下面的代码是可以直接运行的。对,不需要main函数!

    0、导入文件 require

        搜索目录加载文件,并判断是否文件是否已经加载,避免重复加载同一文件。

        其中:".lua" 可以省略。

        require "hello.lua"

        require("hello2")

        require "hello3"

    1、数据类型

        > 在Lua中,定义一个变量的时候,不需要写数据类型

        > Lua中就直接这样定义:a = 10; b = "Hello World" 。

        

    2、注释

        (1)单行注释: --

        (2)多行注释: --[[    --]]

        

    3、输出语句

        

    4、保留关键字

        

    5、运算符

     5.1、算术运算符

        > 其中 ^ 幂运算

        

     5.2、关系运算符

        > 其中 ~= 不等于

        

     5.3、逻辑运算符

        > Lua里的逻辑运算符不是返回 true/false ,而是 a 或者 b。

        > 其中,三目运算符可以表示成如下所示。

        

        使用举例:

            a = 10。

            (1)第一个判断:a>=0为真,故表达式返回的值为 a<=5 

                    而a<=5为假,所以 a>=0 and a<=5 为假,不执行print("111")

            (2)继续判断第二个,a<=9为假,故表达式返回值为 a>=11 

                    而a>=11为假,所以 a<=9 or a>=11 为假,不执行print("222")

            (3)其余情况,执行 print("333")

            

     5.4、拼接运算符

        > 两个点 .. 为字符串的拼接运算。

        

     5.5、优先级

        > 其中 ^ 和 .. 为右链接,其余为从左到右依次运算。

        > 优先级如下:

    6、变量赋值、以及作用域

        (1)局部变量(local)、全局变量。

        

        (2)多重赋值

            > 赋值等号左边为变量,右边为所赋的值。会按顺序依次赋值。

        

    7、代码块

        > 使用 do end

        

    8、控制语句

        

        这里可能涉及到表(table)的知识,这个在后续会介绍。

     8.1、条件语句 if-else-then

        > elseif 中间没有空格。

        > 不要忘了后面的 then

        

     8.2、循环语句 while-do

        > 和C++中的用法类似。

        

     8.3、循环语句 repeat-until

        > 和C++中的 do-while 用法类似。

        

     8.4、循环语句 for-do

        使用for循环语句是Lua中最常用的。

        (1)用法一:数值遍历

        

        (2)用法二:数组遍历

        

        (3)用法三:数组遍历(ipairs)

            > 使用 for key, var in ipairs(t) do    end

        

        (4)用法四:表遍历(pairs)

            > 遍历整张表,输出表中所有数据。

            > 使用 for key, var in pairs(t) do    end

        

        (5)ipairs 与 pairs 的区别

            > ipairs :主要用于表数组的遍历,即表的下标均为正整数,且从1~n连续。

                        不能返回nil,只能返回数字0,如果遇到nil则推出。

                        它只能遍历到表中出现的第一个不是整数的键。

            > pairs  :用于遍历整张表。

                        可以遍历表中所有的键,且除了迭代器本身以及遍历表本身还可以返回nil

    9、函数 function

        函数的定义如下:

        (1)function 函数名(参数列表) 语句块 end

        (2)函数名 = function(参数列表) 语句块 end

        

     9.1、可变参数

        在函数的参数列表最后面使用三个点 ... ,表示输入参数可变。

        而可变的参数会保存在一个表数组 arg 中。

        

     9.2、多返回值

        函数可以返回多个值。

        举例说明:

        

     9.3、函数多返回值的丢失

        -- :如果fun为表达式最后一个所有返回值将被返回

        -- :如果fun不是最后一个    只有第一个值被返回

        

     9.4、函数闭包

        先来看一下闭包的一个例子。

        

        我们可以发现newCounter()里有一个局部变量i,并且函数的返回值是闭包内的函数

        (1)定义:

            > newCounter()      :父函数;

            > 局部变量i         :父函数内的局部变量;

            > 返回值匿名函数    :父函数内的子函数。

        (2)函数返回值为一个子函数,且子函数可以使用父函数内的局部变量i。

        如果你知道了Lua中的函数也可以像变量一样进行赋值的话,你就不难理解上诉的三个print的输出为什么是那样的。

        实际上,上诉代码中的 c1 和 c2 被赋予的值就是闭包内的匿名函数。而执行 c1()、c2() 就相当于是调用一次闭包newCounter()中的匿名函数。

        这就类似创建了一个C++类的实例对象(假设实例对象名为obj)。

        类里面有一个成员变量i,以及一个成员函数。而c1()指向的是该实例对象中的成员函数。

        所以每调用一次c1(),就相当于是执行了一次 obj->匿名函数() 。这样就改变了对象obj里的成员变量i的值。

        而Lua闭包中创建的 c1、c2 就相当于是创建了两个这样的实例对象(obj1,obj2)。所以每执行它们一次,对象内部的变量i的值都会发生变化。

        也有这样的一个比喻:Lua中的闭包类似于一个C++函数,而函数内部的变量i相当于是一个函数中的静态变量。

        再来一个例子:(有了上述形象的类比,相信你能看懂下面的代码)

        

        这就相当于创建了一个C++类的实例对象obj。

        类里面有一个成员变量i,以及两个成员函数InnerFunc1()、和InnerFunc2()。

        而 a、b 分别指向的是该实例对象obj中的成员函数InnerFunc1()、和InnerFunc2()。

        调用一次 a() :就相当于是执行了一次obj->InnerFunc1() 。

        调用一次 b() :就相当于是执行了一次obj->InnerFunc2() 。

    10、表(table)

        Lua中的数据结构只有一个:表(table)。

        原理:键值对 key - value

     10.1、表示一个数组

        前提条件为:数组的下标均为正整数,且连续赋值。

        并且在Lua中,数组的下标从 1 开始。( t[1] , t[2] , t[3] ...)

        (1)数组的定义:

                t = { 值1 , 值2 , 值3 , ... , 值n }

        (2)获取数组元素个数:使用 # 

                #t

        举例:

        

     10.2、表的用法

        (1)初始化赋值

        

        (2)表成员的使用方法

        

        

        (3)补充

            下标不一定是整数或字符串,也可以使浮点数。

                t = { [91.23] = true }

                t[91.23] = false


    【补充知识】

    1、两个对象的比较

    1 2 3 "0"  ==  0         --  false 2  <  15           --  true "2"  <  "15"       --  false  (字典序)

    2、数值与字符串运算(+-*/)

        string 和 numbers 进行运算时,string会被转化成数值进行运算

    1 2 3 4 5 6 print( "10"  +  1 )         -->  11 print( "10"  +  "1" )       -->  11 print( "20"  *  "3" )       -->  60   -- 拼接运算符 print( "10"  ..  1 )        -->  101

    3、求数组的长度(使用 #)

    1 2 a = { 1 , 2 , 3 , 4 , 5 } print(#a)        --  5


        基础语法讲完了,请待下回分解。。。

    转载请注明原文地址: https://ju.6miu.com/read-497.html

    最新回复(0)