• Lua基础语法讲解


    Lua 是什么?

    Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。

    Lua 是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组,由Roberto IerusalimschyWaldemar Celes Luiz Henrique de Figueiredo所组成并于1993年开发。

    设计目的

    其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。

    Lua 特性

    • 轻量级: 它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。
    • 可扩展: Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是CC++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。
    • 其它特性:
      • 支持面向过程(procedure-oriented)编程和函数式编程(functional programming)
      • 自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象;
      • 语言内置模式匹配;闭包(closure);函数也可以看做一个值;提供多线程(协同进程,并非操作系统所支持的线程)支持;
      • 通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承和重载等。

    Lua 基本语法

    Lua 学习起来非常简单,我们可以创建第一个 Lua 程序!

    交互式编程

    Lua 提供了交互式编程模式。我们可以在命令行中输入程序并立即查看效果。

    Lua 交互式编程模式可以通过命令 lua -i lua 来启用:

    $ lua -i

    $ Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio

    在命令行中,输入以下命令:

    > print("my name is jack lee")

    接着我们按下回车键,输出结果如下:

    > print("my name is jack lee")

    my name is jack lee

    脚本式编程

    我们可以将 Lua 程序代码编写到一个以 lua 结尾的文件,并执行,该模式称为脚本式编程,如我们将如下代码存储在名为 name.lua 的脚本文件中,并且将脚本放在D:

    print("my name is jack!")

    print("welcome learn lua follow teacher li!")

     

    使用 lua 名执行以上脚本,输出打印结果

    lua d:Lua ame.lua

    注释

    单行注释

    两个减号是单行注释:

    --

    多行注释

    --[[

     多行注释

     多行注释

     --]]

    变量,函数命名规范

    标示符表示一个变量,函数或其他定义项,命名规范以一个字母 A 到 Z 或 a 到 z 或下划线 _后加上字母,下划线 _数字(0到9)。建议不要使用下划线加大写字母的标示符,因为Lua的保留字也是这样的。

    一般约定,以下划线开头连接一串大写字母的名字(比如 _VERSION)被保留用于 Lua 内部全局变量。

    Lua 不允许使用特殊字符如 @, $, 和 % 来定义成员名 Lua 是一个区分大小写的编程语言。因此在 Lua 中 Run 与 run 是两个不同的标示符。以下列出了一些正确的标示符:

    mohd         zara      abc     move_name    a_123

    myname50     _temp     j       a23b9        retVal

    关键词

    以下列出了 Lua 的保留关键字。保留关键字不能作为常量或变量或其他用户自定义标示符:注:(以下关键字后续会详细讲解)

    and

    break

    do

    else

    elseif

    end

    false

    for

    function

    if

    in

    local

    nil

    not

    or

    repeat

    return

    then

    true

    until

    while

    全局变量

    在默认情况下,变量总是认为是全局的。

    全局变量不需要声明,给一个变量赋值后即创建了这个全局变量,访问一个没有初始化的全局变量也不会出错,只不过得到的结果是:nil

    > print(b)

    nil

    > b=10

    > print(b)

    10

    你可以设置全局变量为空,只需要将变量赋值为nil

    b = nil

    print(b)      --> nil

    这样变量b就好像从没被使用过一样。换句话说, 当且仅当一个变量不等于nil时,这个变量即存在。

     

    Lua 数据类型

    Lua是动态类型语言,变量不要类型定义,只需要为变量赋值。 值可以存储在变量中,作为参数传递或结果返回。

    Lua中有8个基本类型分别为:nilbooleannumberstringuserdatafunctionthreadtable (注:以下数据类型后续做详细讲解)

    数据类型

    描述

    nil

    表示一个无效值(在条件表达式中相当于false)。

    boolean

    包含两个值:falsetrue

    number

    表示双精度类型的实浮点数

    string

    字符串由一对双引号或单引号来表示 "" ''

    function

    函数

    userdata

    表示任意存储在变量中的C数据结构

    thread

    表示执行的独立线程,用于执行协同程序

    table

    Lua 中的表(table)其实是一个"关联数组",数组的索引可以是数字或者是字符串。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。

    我们可以使用type函数测试给定变量或者值的类型:

    在sublime编辑器中写下以下代码, Ctrl+B 编译。

    _str="I am str"

    _number=10.116

    _bo=false

     

    print(type(str))

    print(type(_number))

    print(type(_bo))

     

    数据类型具体分析:

    nil(空)

    nil 类型表示一种没有任何有效值,它只有一个值 -- nil,例如打印一个没有赋值的变量,便会输出一个 nil 值:

    > print(type(a))

    nil

    boolean(布尔)

    boolean 类型只有两个可选值:true(真) 和 false(假),Lua false nil 看作是"",其他的都为""

    number(数字)

    Lua 默认只有一种 number 类型 -- double(双精度)类型,以下几种写法都被看作是 number

    print(type(2))

    print(type(2.2))

    print(type(0.2))

    string(字符串)字符串由一对双引号或单引号来表示。

    string1 = "this is string1"

    string2 = 'this is string2'

    也可以用 2 个方括号 "[ [ ] ]" 来表示"一块"字符串。

    _str2=[[my name is jack!]]

    print(_str2)

     

    在对一个数字字符串上进行算术操作时,Lua 会尝试将这个数字字符串转成一个数字:

    print("1"+5)                 --6

    print("1"+"6")              --7

    print("3+7")              -- "3+7"

    关于字符串拼接,使用.. 对字符串进行拼接

    value=11

    print("value="..value)    --value=11

    使用 # (井号)来计算字符串的长度,放在字符串前面,如下实例:

    mail = "ukraine_lee@163.com"

    print(#mail)

    --19

    Table(表)

    Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是大括号{},用来创建一个空表。也可以在表里添加一些数据,直接初始化表:

    -- 创建一个空的 table

    local tbl1 = {}

    -- 直接初始表

    local tbl2 = {"apple", "pear", "orange", "grape"}  --苹果,梨,橙子,葡萄

     

    local tbl2={X=3,y=4} --指定键值初始化  X,Y是键,值是3,4

    Lua 中的表(table)其实是一个"关联数组",数组的索引可以是数字或者是字符串。(类似字典)

    _table_1={}

    _table_1["str_key1"]="str_value"

    _table_1["str_key2"]=2

    nub_key1=1

    _table_1[nub_key1]="value1"

    nub_key2=2

    _table_1[nub_key2]=13

    _table_1[nub_key2]=_table_1[nub_key2]+1

    for k,v in pairs(_table_1) do

    print(k.."===="..v)

    end

    不同于其他语言的数组把 0 作为数组的初始索引,在 Lua 里表的默认初始索引一般以 1 开始。

    local tbl = {"apple", "pear", "orange", "grape"}

    for key, val in pairs(tbl) do

        print("Key", key)

    end

    -- 1 2 3 4

    table 不会固定长度大小,有新数据添加时 table 长度会自动增长,没初始的 table 都是 nil。

    _table = {}

    for i = 1, 10 do

        _table[i] = i

    end

    -- for k,v in pairs(_table) do

    -- print(k,v)

    -- end

    _table["key"] = "val"

    print(_table["key"])

    print(_table["none"])

    for k,v in pairs(_table) do

    print(k,v)

    end

    表函数的定义和使用:

    tab={x=2,y=3}

    function tab:setValue(m_x,m_y)  --注意定义的时候使用了:冒号

    tab.x=m_x

    tab.y=m_y

    end

    tab:setValue(5,6)    --注意,在调用的时候也必须和定义时一致使用冒号。

    print(tab.x,tab.y)

    function(函数)

    函数的基本语法:

    function function_name(n_value)

    return n_value+1

    end

    print(function_name(7))

    函数还可以像下面这样存在一个变量里:

    function function_name(n_value)

    return n_value+1

    end

    print(function_name(7))

    func_self=function_name

    print(func_self(5))

    function 可以以匿名函数(anonymous function)的方式通过参数传递:

    --首先写一个函数 有个2个参数 1是表 2是函数  --遍历表 取出键值

    --打印调用func将 键值作为参数传递进func

    function anonymous(tab,func)

    for k,v in pairs(tab) do

    print(func(k,v))

    end

    end

    --调用anonymous   1参传入表,2参是匿名函数并且有执行内容,--内容是返回_k _v 注--意函数结尾需要有end

    _table={key1="value1",key2="value2"}

    anonymous(_table,function(_k,_v)

    return _k,_v

    end)

     

    thread(线程)

    Lua 里,最主要的线程是协同程序(coroutine)。拥有自己独立的栈、局部变量和指令指针,可以跟其他协同程序共享全局变量和其他大部分东西。

    线程跟协程的区别:线程可以同时多个运行,而协程任意时刻只能运行一个,并且处于运行状态的协程只有被挂起(suspend)时才会暂停。

    userdata(自定义类型)

    userdata 是一种用户自定义数据,用于表示一种由应用程序或 C/C++ 语言库所创建的类型,可以将任意 C/C++ 的任意数据类型的数据(通常是 struct 和 指针)存储到 Lua 变量中调用。(简单来说就是在LUA中用userdata表示其他语言的数据类型)

    Lua 变量

    变量在使用前,必须在代码中进行声明,即创建该变量,Lua 中的变量全是全局变量,那怕是语句块或是函数里,除非用 local 显式声明为局部变量,

    局部变量的作用域为从声明位置开始到所在语句块结束,变量的默认值均为 nil。

    variable_1=1  --全局

    local variable_2 = 2 --局部

    function function_name()

    variable_3=3 --全局

    local variable_4 = 4 --局部

    return variable_3+variable_2--(注意 variable_2是在外面声明的局部变量,本质也是全局的)

    end

    print(function_name())

    print("variable_3="..variable_3)

    print("variable_4=",variable_4)-- 注意不能使用".."连接一个空值

    赋值语句

    赋值是改变一个变量的值和改变表域的最基本的方法。

    value=1

    strValue="str"

    value_2=value+2

    print(strValue)

    ---------------------------------------------------------

    _table={n="n_vale",m="m_value"}

    print(_table.n)

    _table.n=11

    print(_table.n)

    Lua 循环

    很多情况下我们需要做一些有规律性的重复操作,因此在程序中就需要重复执行某些语句。

    一组被重复执行的语句称之为循环体,能否继续重复,决定循环的终止条件。

    循环结构是在一定条件下反复执行某段程序的流程结构,被反复执行的程序被称为循环体。

    循环语句是由循环体及循环的终止条件两部分组成的。

     

    while 循环

    Lua 编程语言中 while 循环语句在判断条件为 true 时会重复执行循环体语句。

    语法

    Lua 编程语言中 while 循环语法(注意不同于C# 语句没有大括号)

    while(condition)

    do

       statements

    end

    statements(循环体语句) 可以是一条或多条语句,condition(条件) 可以是任意表达式,在 condition(条件)  true 时执

    实例:

    a=1

    while( a < 5 )

    do

       print("a 的值为:", a)

       a = a+1

    end

     

    Lua for 循环

    Lua 编程语言中 for 循环语句可以重复执行指定语句,重复次数可在 for 语句中控制。

    Lua 编程语言中 for语句有两大类:(注意与C#的for 循环有较明显区别)

    第一种:数值for循环

    for var=exp1,exp2,exp3 do

    <执行体>

    end

    var从exp1变化到exp2,每次变化以exp3为步长递增var,并执行一次"执行体"。exp3是可选的,如果不指定,默认为1。

    实例:

    for i=1,5 do

    print(i)

    end

    ---------------------------------------------------

    function function_name(x)

    return x*2

    end

    for i=1,function_name(3) do

    print(i)

    end

    第二种:泛型for循环

    泛型for循环通过一个迭代器函数来遍历所有值

     

    lua中pairs与ipairs两个迭代器的用法相近,但有一点是不一样的:

    pairs可以遍历表中所有的key,包含索引,和自定义类型key

    ipairs 仅可以遍历出具备索引的值

     

    _table2={"Suanday","Monday"}

    _table2["ukey"]="uvalue" --键值都是字符串

    intkey=8

    _table2[intkey]="uvalue" --键是number 值是字符串

    for k,v in ipairs(_table2) do

    print(k,v)

    end

    输出结果是 table2 中仅具备索引的2个值被输出了)

    -- 1 Suanday

    -- 2 Monday

     

    for k,v in pairs(_table2) do

    print(k,v)

    end

    输出结果是(所有的键值均被输出)

    --1   Suanday

    --2  Monday

    --ukey  uvalue

    --8   uvalue

     

    Lua break 语句

    Lua 编程语言 break 语句插入在循环体中,用于退出当前循环或语句,并开始脚本执行紧接着的语句。

    如果你使用循环嵌套,break语句将停止最内层循环的执行,并开始执行的外层的循环语句。

    a=1

    while(a<6)

    do

    print(a)

    a=a+1

    if(a>3)

    then

    break

    end         --注意if语句需要关键字 then和end

    end   --这个 end 是while 语句的结束

     

    无限循环

    在循环体中如果条件永远为 true 循环语句就会永远执行下去,以下以 while 循环为例:

    while( true )

    do

       print("循环将永远执行下去")

    end

     

    Lua  if 语句

    Lua if 语句 由一个布尔表达式作为条件判断,其后紧跟其他语句组成。

    Lua if 语句语法格式如下:

    if(布尔表达式)

    then

       --[ 在布尔表达式为 true 时执行的语句 --]

    end

    a=1

    if(a>0)

    then

    a=a+1

    print(a)

    end

    if...else 语句

    Lua if 语句可以与 else 语句搭配使用, 在 if 条件表达式为 false 时执行 else 语句代码块。

    Lua if...else 语句语法格式如下:

    if(布尔表达式)

    then

       --[ 布尔表达式为 true 时执行该语句块 --]

    else

       --[ 布尔表达式为 false 时执行该语句块 --]

    end

     

    if...elseif...else 语句

    Lua if 语句可以与 elseif...else 语句搭配使用, 在 if 条件表达式为 false 时执行 elseif...else 语句代码块,用于检测多个条件语句。

    Lua if...elseif...else 语句语法格式如下:

    if( 布尔表达式 1)

    then

       --[ 在布尔表达式 1 为 true 时执行该语句块 --]

    elseif( 布尔表达式 2)

    then

       --[ 在布尔表达式 2 为 true 时执行该语句块 --]

    elseif( 布尔表达式 3)

    then

       --[ 在布尔表达式 3 为 true 时执行该语句块 --]

    else 

       --[ 如果以上布尔表达式都不为 true 则执行该语句块 --]

    end

    if...else 语句

    Lua if 语句允许嵌套, 这就意味着你可以在一个 if 或 else if 语句中插入其他的 if 或 else if 语句。Lua if 嵌套语句语法格式如下:

    if( 布尔表达式 1)

    then

       --[ 布尔表达式 1 为 true 时执行该语句块 --]

       if(布尔表达式 2)

       then

          --[ 布尔表达式 2 为 true 时执行该语句块 --]

       end

    end

    范例:

    a=1

    if(a>0) then  a=a+1

    if(a==2) then  a=a+11

    end

    print(a)

    end

    Lua 函数

    Lua中,函数是对语句和表达式进行抽象的主要方法。既可以用来处理一些特殊的工作,也可以用来计算一些值。

    Lua 提供了许多的内建函数,你可以很方便的在程序中调用它们,如print()函数可以将传入的参数打印在控制台上。

    Lua 函数主要有两种用途:

    1.完成指定的任务,这种情况下函数作为调用语句使用;

    2.计算并返回值,这种情况下函数作为赋值语句的表达式使用

    function returenMaxValue(v1,v2)

    if(v1>v2)

    then   result=v1

    else

    result=v2

    return result

    end

    end

    print(returenMaxValue(11,19))

    Lua 运算符

    运算符是一个特殊的符号,用于告诉解释器执行特定的数学或逻辑运算。Lua提供了以下几种运算符类型:

    • 算术运算符
    • 关系运算符
    • 逻辑运算符
    • 其他运算符

    算术运算符

    下表列出了 Lua 语言中的常用算术运算符,设定 A 的值为10,B 的值为 20:

     

    操作符

    描述

    实例

    +

    加法

    A + B 输出结果 30

    -

    减法

    A - B 输出结果 -10

    *

    乘法

    A * B 输出结果 200

    /

    除法

    B / A w输出结果 2

    %

    取余

    B % A 输出结果 0

    ^

    乘幂

    A^2 输出结果 100

    -

    负号

    -A 输出结果v -10

    关系运算符

    下表列出了 Lua 语言中的常用关系运算符,设定 A 的值为10,B 的值为 20:

    操作符

    描述

    实例

    ==

    等于,检测两个值是否相等,相等返回 true,否则返回 false

    (A == B) 为 false。

    ~=

    不等于,检测两个值是否相等,相等返回 false,否则返回 true

    (A ~= B) 为 true。

    >

    大于,如果左边的值大于右边的值,返回 true,否则返回 false

    (A > B) 为 false。

    <

    小于,如果左边的值大于右边的值,返回 false,否则返回 true

    (A < B) 为 true。

    >=

    大于等于,如果左边的值大于等于右边的值,返回 true,否则返回 false

    (A >= B) 返回 false。

    <=

    小于等于, 如果左边的值小于等于右边的值,返回 true,否则返回 false

    (A <= B) 返回 true。

    逻辑运算符

    下表列出了 Lua 语言中的常用逻辑运算符,设定 A 的值为 trueB 的值为 false

    操作符

    描述

    实例

    and

    逻辑与操作符。 若 A false,则返回 A,否则返回 B

    (A and B) false

    or

    逻辑或操作符。 若 A true,则返回 A,否则返回 B

    (A or B) true

    not

    逻辑非操作符。与逻辑运算结果相反,如果条件为 true,逻辑非为 false

    not(A and B) true

    其他运算符

    下表列出了 Lua 语言中的连接运算符与计算表或字符串长度的运算符:

    操作符

    描述

    实例

    ..

    连接两个字符串

    a..b ,其中 a "Hello " b "World", 输出结果为 "Hello World"

    #

    一元运算符,返回字符串或表的长度。

    #"Hello" 返回 5

    Lua 字符串

    字符串或串(String)是由数字、字母、下划线组成的一串字符。

    Lua 语言中字符串可以使用以下三种方式来表示:

    单引号间的一串字符。

    双引号间的一串字符。

    和[[ ]]间的一串字符。

    范例:

    str_1="stringtype_1"

    str_2='stringtype_2'

    str_3=[["stringtype_3"]]

    print(str_1)

    print(str_2)

    print(str_3)

    字符串操作

    result=string.upper("upper") //字符串转大写

    print(result)

    result=string.lower("LOWER")//字符串转小写

    print(result)

    result=string.reverse("reverse ")//字符串翻转

    print(result)

    result=string.len("len")//字符串长度

    print(result)

    字符串格式化

    Lua 提供了 string.format() 函数来生成具有特定格式的字符串, 函数的第一个参数是格式 , 之后是对应格式中每个代号的各种数据。

    字符串格式化

    str_1="aaa"

    str_2="bbb"

    result =string.format("%s,%s",str_1,str_2)

    print(result)

    日期格式化:

    day=1

    month=5

    year=2017

    date=string.format("日期:%02d/%02d/%03d",day,month,year)

    print(date)

    Lua 数组

    数组,就是相同数据类型的元素按一定顺序排列的集合,可以是一维数组和多维数组。

    Lua 数组的索引键值可以使用整数表示,数组的大小不是固定的。

    array={"hu","hj"}

    for i=0,2 do

    print(array[i])

    end

    --nil

    -- hu

    -- hj

    -- 我们发现上述代码,索引为0时,从输出了nil  lua数组索引默认为1.

    正如你所看到的,我们可以使用整数索引来访问数组元素,如果知道的索引没有值则返回nil

    Lua 索引值是以 1 为起始,但你也可以指定 0 开始。

    除此外我们还可以以负数为数组索引值:

    array={}

    for i=-10,0 do

    array[i]=i*2

    print(array[i])

    end

     

    多维数组

    array={}

    for i=1,3 do

    array[i]={}

    for j=1,3 do

    array[i][j]=i*j

    end

    end

    for i=1,3 do

    for j=1,3 do

    print(array[i][j])

    end

    end

    -- 123

    -- 246

    -- 369

     

    Lua 迭代器

    泛型 for 迭代器

    泛型 for 在自己内部保存迭代函数,实际上它保存三个值:迭代函数、状态常量、控制变量。

    泛型 for 迭代器提供了集合的 key/value 对,语法格式如下:

    for k, v in pairs(t) do

        print(k, v)

    end

    范例代码:

    table={"huhu","jack","ukraine"}

    for k,v in pairs(table) do

    print(k,v)

    end

    Lua table()

    table 是 Lua 的一种数据结构,用来帮助我们创建不同的数据类型,如:数字、字典等。

    Lua table 使用关联型数组,你可以用任意类型的值来作数组的索引,但这个值不能是 nil。

    Lua table 是不固定大小的,你可以根据自己需要进行扩容。

    table()的构造

    构造器是创建和初始化表的表达式。表是Lua特有的功能强大的东西。最简单的构造函数是{},用来创建一个空表。

    -- 初始化表

    mytable = {}

    -- 指定值

    mytable[1]= "Lua"  --使用数字作为键

    table["strKey"]="value"  --使用字符串作为键的写法1

    table.strKey="value"  --使用字符串作为键的写法2

     

    -- 移除引用

    mytable = nil

    -- lua 垃圾回收会释放内存

    范例代码-1:

    table={"value1","value2"}

    table["other1"]="other_value1"

    table["other2"]=" other_value2"

    for k,v in pairs(table) do

    print(k,v)

    end

    --1 value1

    --2 value2

    --other1 other_value1

    --other2 other_value2

    范例代码-2:

    m_table={"a","b","c"}

    print("m_table类型是=",type(m_table))

    temp_table=m_table

    print("temp_table指向m_table,temp_table[1]=",temp_table[1])

    temp_table[1]="aa"  --修改m_table[1]的值

    temp_table=nil

    print("释放temp_table后 m_table[1]=",m_table[1])

    Table连接:

    m_table={"a","b","c"}

    temp=table.concat(m_table) --注意table是关键字

    print(temp)

    插入和移除:

    插入:

    m_table={"a","b","c"}

    table.insert(m_table,"d")

    print(m_table[4])

    移除:

    table.remove(m_table) --移除方法,会移除最后一个元素

    for k,v in pairs(m_table) do

    print(k,v)

    end

    排序:

    字母排序:

    str={"a","d","b","c"}

    for k,v in pairs(str) do

    print("排序前:"..k..":"..v)

    end

    table.sort(str)

    for k,v in pairs(str) do

    print("排序后:"..k..":"..v)

    end

    数字排序:

    a=1

    b=2

    c=3

    d=4

    str={a,d,b,c}

    for k,v in pairs(str) do

    print("排序前:"..k..":"..v)

    end

    table.sort(str)

    for k,v in pairs(str) do

    print("排序后:"..k..":"..v)

    end

  • 相关阅读:
    【转】由浅入深表达式树(一)创建表达式
    【转】背后的故事之
    【转】背后的故事之
    【转】C#集合类型大盘点
    【转】最近用Timer踩了一个坑,分享一下避免别人继续踩
    【转】《深入理解C# 3.x的新特性》博文系列汇总
    【转】文件各种上传,离不开的表单
    【转】文件下载之断点续传(客户端与服务端的实现)
    【转】权限管理学习 一、ASP.NET Forms身份认证
    【转】C#单元测试,带你快速入门
  • 原文地址:https://www.cnblogs.com/AaronBlogs/p/7111056.html
Copyright © 2020-2023  润新知