要 1.基本数据类型 2.Lua中的常用语句结构以及函数 3.Lua中的常用语句结构介绍 4.Lua中的库函数

Lua的语法基础超级简单,非常易于上手,下面总结一些学习过程中的Lua语法基础:

在开始学习之前,先介绍一些最基本的概念,在Lua中具有一个代码块的概念,每个函数或者for循环等都是一个代码块。在Lua中,用 “- - ”来标记该行的注释,使用“- - [ [” 和   “ - - ] ] ”之间括起来的部分进行块注释。如下所示:

[plain] view plaincopy

  1. -- 行注释,仅仅注释当前行

  2. for idx = 1, 10 do  --在代码之后进行行注释

  3. print("idx=",idx);

  4. end

  5. --[[

  6. 块注释,上边的for循环结构跟end结合起来就是一个Lua中常见的代码块结构。

  7. --]]

另外,Lua中支持的算术运算符有:+、-、*、/,即加、减、乘、除;支持的关系运算符有:==、~=(不等于)、<、>、<=、>=;支持的逻辑运算符有:and、or、not。需要注意的是,在Lua中,and逻辑运算符如果第一个参数是false,则返回false,不会执行第二个参数的代码(即使第二个参数是一个错误的表达式,也能顺利运行);如果第一个参数是true,返回第二个参数的值。 同理,or逻辑运算符如果第一个参数不是false,则返回第一个参数的值(不会执行第二个参数的代码);否则返回第二个参数的值。这就是所谓的逻辑运算符短路求值

[plain] view plaincopy

  1. result = true

  2. if result and an_donot_defined_method() then

  3. print("no erro occured!")

  4. end

  5. --[[

  6. 上述代码输出的错误如下:

  7. stdin:1: attempt to call global 'an_donot_defined_method' (a nil value)

  8. stack traceback:

  9. stdin:1: in main chunk

  10. [C]: ?

  11. --]]

  12. result =false

  13. if (result and an_donot_defined_method())==false  then

  14. print("no erro occured!")

  15. end

  16. --上述代码顺利通过编译,即使有一个没定义的方法,打印结果:no erro occured!

一、基本数据类型

Lua中具有5种基本的数据类型,nil、Boolean、string、Number和table在Lua中使用变量不需要提前声明,变量的类型决定于用户赋值的类型可以使用 type()函数判断变量的类型。其中,nil、Boolean、Number都是用法比较简单的类型,string、table类型用法稍微复杂点。给一个变量赋值为nil,表示释放该变量。Boolean跟其他语言一样,只有true和false两种值。Number是双精度浮点数,Lua中没有整数类型。table类型可以当作数组使用。

         在Lua中,变量默认是全局的,这通常导致一些调试困难,最好尽量显式的在变量名之前加上 local 关键字声明该变量为局部变量。

[plain] view plaincopy

  1. gNumber = 10  --这是一个默认全局的变量

  2. print(type(gNumber))

  3. --输出结果为number

  4. gNumber = nil --之前的number类型gNumber = 10变量被释放

  5. print(type(gNumber))

  6. --输出结果为nil

  7. function LocalVarFunction ()

  8. local pTable = {} --用local关键字声明一个局部变量,这个变量将在执行LocalVarFunction方法后销毁

  9. for idx = 1, 5 do

  10. local result = true  --这个result将在每个for循环执行之后销毁

  11. if result then

  12. local pString = "这个字符串将在if代码块之后销毁"

  13. pTable[idx] = pString

  14. print(pTable[idx])

  15. end

  16. end

  17. end

      下面详细介绍string以及table两种类型的详细用法。

1、string类型的用法

       Lua中的字符串操作非常出色。下表是一些特殊意义的字符:

特殊的Lua字符串

 字符 意义 字符 意义
     \a 响铃     \v  垂直制表符 
    \b 退格     \\ 反斜杠
    \f 换页符     \“ 双引号
    \n 换行符     \' 单引号
    \r 换行符    \[ 左方括号
   \t 制表符    \] 右方括号

a、类型转换

Lua会根据上下文在合理合法的情况下隐式进行数字和字符之间的转换。另外,也可以使用tonumber()函数和tostring()函数显式地进行字符与数字的转换。 见代码实例:

[plain] view plaincopy

  1. --字符与数字的隐式转换

  2. print("10" + 7)

  3. --输出结果为:17,将字符10隐私转化为Number类型计算

  4. print("hello" + 7)

  5. --无法进行运算,即不能隐式将"hello"字符转化为Number计算

  6. --[[

  7. 系统错误如下:

  8. stdin:1: attempt to perform arithmetic on a string value

  9. stack traceback:

  10. stdin:1: in main chunk

  11. [C]: ?

  12. --]]

  13. --字符与数字的显式转换

  14. print(tonumber("100")+11)

  15. --输出结果为:111

  16. print(type(tostring(100)))

  17. --输出结果为:string

b、常用的字符处理函数介绍    string.char()函数根据传入的ASCII编码返回该编码对应的字符。如:string.char(10),表示字符换行符,10是换行符的ASCII编码。

    string.len()函数求字符串的长度。如:

[plain] view plaincopy

  1. print(string.len("hello"))

  2. --输出结果为:5

 string.sub(aString, start, end) 函数返回指定字符串的子串。如:

[plain] view plaincopy

  1. gString = "hello Lua"

  2. print(string.sub(gString, 7,9))

  3. --输出结果为:Lua

string.format()函数格式化输出指定字符串。%s表示字符串,%d表示所有数字,%D表示非数字,%a表示字母,%c表示控制字符,%l小写字母,%p标点符号,%s空格符号,%u大写字母,%w字母数字,%x十六进制数,%z用0表示的字符。加%前缀可以让特殊符号也能用在格式化中(如:().%+_*?[ ^ $ ]),如%%代表百分比符号。%.4f表示小数点后有4位的浮点数,%02d.表示至少有两个数字的整数,如果不足两个数字则用0补足。如:

[plain] view plaincopy

  1. aString = "哈哈,你是"

  2. bString = "一头猪"

  3. print(string.format("%s%s", aString, bString))

  4. --输出结果为:哈哈,你是一头猪

sting.find(sourceString, targetString) 函数在sourceString字符串中查找第一个符合targetString字符串的位置,如果找到则返回开始和结束的位置,没找到则返回nil。

 string.gsub(sourceString, pattern, replacementString) 函数返回一个字符串,sourceString字符中满足pattern格式的字符都会被替换成replacementString参数的值。

string.gfind(sourceString, pattern) 函数遍历一个字符串,一旦查找到符合指定格式的字符串就返回该子串。

2、table类型的用法

一般table可以当做数组使用,可以通过table[n]的索引形式访问任意数组中的某个成员。在Lua中,table还能被当做字典dictionary数据使用,并且数组跟字典的用法还能混合使用(实质上还是数组,只不过索引从数字变成其他属性值)。

a、使用其他值作为table的索引以及多维table

 table还可以使用其他的值作为索引值,并且能用数字跟其他值同时作为同一个table的索引。如:

[plain] view plaincopy

  1. gTable = {}

  2. gTable.name = "eric"

  3. gTable.gender = "man"

  4. gTable.phonenumber = "0000000000"

  5. gTable[1] = "公司"

  6. gTable[2] = "部门"

  7. for index, value in pairs(gTable) do

  8. print(index, value)

  9. end

  10. --[[

  11. 输出结果如下:

  12. 1   公司

  13. 2   部门

  14. phonenumber 0000000000

  15. gender  man

  16. name    eric

  17. --]]

注意,上述循环中的pairs()函数可以遍历table中的每一对值(索引以及索引对应的value,有点类似字典,不是吗?)

事实上,table的索引还可以是table本身,这样就组成了一个多维table或多维字典。跟其他语言的多维数组或字典比起来,使用真是超级方便,非常非常的灵活。如:

[plain] view plaincopy

  1. gTable = {}

  2. gTable.name = "eric"

  3. gTable.gender = "man"

  4. gTable.phonenumber = "0000000000"

  5. gTable[1] = "公司"

  6. gTable[2] = "部门"

  7. gTable.hobby = {"跑步", "读书", "游戏", "动漫"}  -- 多维table,可以通过gTable.hobby[1]的方式访问.即gTable.hobby本身也是一个table

  8. gTable.secTable = {}

  9. gTable.secTable.job = "程序员"

  10. gTable.secTable.label = "写代码的"

  11. gTable.secTable.description = "职责是实现产品的逻辑"

  12. for index, value in pairs(gTable) do

  13. print(index, value)

  14. if ("table" == type(value)) then

  15. for idx, var in pairs(value) do

  16. print("二维table:", idx, var)

  17. end

  18. end

  19. end

  20. --[[

  21. 输出结果如下:

  22. 1   公司

  23. 2   部门

  24. hobby   table: 0x7fdceac14bc0

  25. 二维table:    1   跑步

  26. 二维table:    2   读书

  27. 二维table:    3   游戏

  28. 二维table:    4   动漫

  29. phonenumber 0000000000

  30. gender  man

  31. secTable    table: 0x7fdceac15100

  32. 二维table:    label   写代码的

  33. 二维table:    description 职责是实现产品的逻辑

  34. 二维table:    job 程序员

  35. name    eric

  36. --]]

b、table 的常用函数

table.getn()函数,返回table中元素的个数。如:

[plain] view plaincopy

  1. gStringTable = {"a", "b","c","d","e"}

  2. for i = 1, table.getn(gStringTable) do

  3. print(gStringTable[i])

  4. end

table.sort()函数,将table中的元素从小到大排列。如:

[plain] view plaincopy

  1. gNumberTable = {10, 5, 7, 2,3, 2}

  2. table.sort(gNumberTable)

  3. for i = 1, table.getn(gNumberTable) do

  4. print(gNumberTable[i])

  5. end

  6. --输出结果如下:

  7. 2

  8. 2

  9. 3

  10. 5

  11. 7

  12. 10

    table.insert(pTable, position, value) 函数在table中插入一个新值,位置参数如果没指定,则默认将新值插入到table的末尾。

table.remove(pTable, position) 函数从指定table中删除指定位置的元素并返回该元素,如果没有指定删除的位置,则默认删除table的最后一个元素。

介绍到这里, Lua中基本的数据类型诸位应该都能掌握,休息一下,下面接着开始简单介绍Lua的基本语句以及函数。

二、Lua中的常用语句结构以及函数

1、Lua中的常用语句结构介绍

[plain] view plaincopy

  1. --if 语句结构,如下实例:

  2. gTable = {"hello", 10}

  3. if nil ~= gTable[1] and "hello" == gTable[1] then

  4. print("gTable[1] is" , gStringTable[1])

  5. elseif  10 == gTable[2] then

  6. print("gTable[2] is", gTable[2])

  7. else

  8. print("unkown gTable element")

  9. end

[plain] view plaincopy

  1. --while 和repeat循环语句结构,while先判断条件,如果true才执行代码块(有可能跳过该代码块);repeat则是在最后判断条件,保证代码块至少执行一次。

  2. gTable = {1,2,3,4,5,6,7,8,9,10}

  3. index = 1

  4. while gTable[index] < 10 do

  5. print("while gTable[",index,"] is ",gTable[index])

  6. index = index + 1 -- 注意,Lua不支持index++或者index += 1形式的运算符。

  7. end

  8. --[[

  9. while循环输出结果如下:

  10. while gTable[   1   ] is    1

  11. while gTable[   2   ] is    2

  12. while gTable[   3   ] is    3

  13. while gTable[   4   ] is    4

  14. while gTable[   5   ] is    5

  15. while gTable[   6   ] is    6

  16. while gTable[   7   ] is    7

  17. while gTable[   8   ] is    8

  18. while gTable[   9   ] is    9

  19. --]]

  20. --上一个循环结束后,index = 10

  21. repeat

  22. print("repeat gTable[",index,"] is ",gTable[index])

  23. index = index - 2

  24. until index < 1

  25. --[[

  26. 输出结果如下:

  27. repeat gTable[  10  ] is    10

  28. repeat gTable[  8   ] is    8

  29. repeat gTable[  6   ] is    6

  30. repeat gTable[  4   ] is    4

  31. repeat gTable[  2   ] is    2

  32. --]]

[plain] view plaincopy

  1. --for循环结构,for循环结构具有三个参数,初始值,结束值,每个循环增加值。

  2. for index = 1, 5 do --不设置第三个参数的话,默认缺省第三个参数是1,即每个循环 index 增加1

  3. print("for cycle index =",index)

  4. end

  5. --[[

  6. 输出结果为:

  7. for cycle index =   1

  8. for cycle index =   2

  9. for cycle index =   3

  10. for cycle index =   4

  11. for cycle index =   5

  12. --]]

  13. for index = 20 , 0, -5 do --设定第三个参数为-5

  14. print("for cycle index:",index)

  15. end

  16. --[[

  17. 输出结果:

  18. for cycle index:    20

  19. for cycle index:    15

  20. for cycle index:    10

  21. for cycle index:    5

  22. for cycle index:    0

  23. --]]

[plain] view plaincopy

  1. --break关键字可以使循环强制退出,Lua中没有continue关键字,需要通过其他方式实现continue关键字,比如if-else语句。或者通过网络下载Lua的continue关键字补丁安装来解决该问题

  2. for index = 1, 100, 5 do

  3. if index > 10 and index < 25 then  --用if-else语句实现continue关键字的功能

  4. print("continue!!!!! index=",index)

  5. else

  6. if index > 15 and index < 35 then

  7. print("break~~~~~index=",index)

  8. break

  9. end

  10. print("At end index=",index)

  11. end

  12. end

  13. --[[

  14. 输出结果如下:

  15. At end index=   1

  16. At end index=   6

  17. continue!!!!! index=    11

  18. continue!!!!! index=    16

  19. continue!!!!! index=    21

  20. break~~~~~index=    26

  21. --]]

[plain] view plaincopy

  1. --最后还要提的一点是,Lua中switch语句的缺失,用if-elseif-else语句代替的话,显得非常臃肿,还有其他的一些实现方案。笔者在网上麦子加菲童鞋的博客中找到一种Lua中代替switch语句非常优雅的方案。下面贴出麦子加菲原代码:

  2. --Switch语句的替代语法(所有替代方案中觉得最好,最简洁,最高效,最能体现Lua特点的一种方案)

  3. action = {

  4. [1] = function (x) print(x) end,

  5. [2] = function (x) print( 2 * x ) end,

  6. ["nop"] = function (x) print(math.random()) end,

  7. ["my name"] = function (x) print("fred") end,

  8. }

  9. while true do

  10. key = getChar()

  11. x = math.ramdon()

  12. action[key](x)

  13. end

2、Lua中的函数

在Lua脚本中,函数是以function关键字开始,然后是函数名称,参数列表,最后以end关键字表示函数结束。需要注意的是,函数中的参数是局部变量,如果参数列表中存在(...)时,Lua内部将创建一个类型为table的局部变量arg,用来保存所有调用时传递的参数以及参数的个数(arg.n)

[plain] view plaincopy

  1. function PrintTable (pTable)

  2. for index = 1, table.getn(pTable) do

  3. print("pTable[",index,"] =",pTable[index])

  4. end

  5. end

  6. gStringTable = {"hello","how","are","you"}

  7. PrintTable(gStringTable)

  8. --[[

  9. 输出结果为:

  10. pTable[ 1   ] = hello

  11. pTable[ 2   ] = how

  12. pTable[ 3   ] = are

  13. pTable[ 4   ] = you

  14. --]]

  15. function PrintFriendInfo (name, gender, ...)

  16. local friendInfoString = string.format("name:%s  gender:%d",name,gender)

  17. if 0 < arg.n then

  18. for index = 1, arg.n do

  19. friendInfoString = string.format("%s otherInfo:%s",friendInfoString, arg[index])

  20. end

  21. end

  22. print(friendInfoString)

  23. end

  24. PrintFriendInfo ("eric", 1, "程序员","2b", 50)

  25. --输出结果为:

  26. -- name:eric  gender:1 otherInfo:程序员 otherInfo:2b otherInfo:50

 Lua函数的返回值跟其他语言比较的话,特殊的是能够返回多个返回值。return之后,该Lua函数从Lua的堆栈里被清理

[plain] view plaincopy

  1. function GetUserInfo ()

  2. local name = "eric"

  3. local gender = 1

  4. local hobby = "动漫"

  5. return name, gender, hobby

  6. end

  7. print(GetUserInfo())

  8. --输出结果:eric 1   动漫

三、Lua中的库函数

在本文的最后,介绍一些Lua中常用的库函数。

          1.数学库

math库的常用函数:三角函数math.sin、math.cos、取整函数math.floor、math.ceil、math.max、math.min、随机函数math.random、math.randomseed(os.time())、变量pi和huge。

2、I/O库

进行I/O操作前,必须先用io.open()函数打开一个文件。io.open()函数存在两个参数,一个是要打开的文件名,另一个是模式字符,类似"r"表示读取、“w”表示写入并同时删除文件原来内容,“a”表示追加,“b”表示打开二进制文件。该函数会返回一个表示文件的返回值,如果打开出错则返回nil,写入之前需要判断是否出错,比如:local file = assert(io.open(filename, “w”))..使用完毕后,调用io.close(file).或file:close()。

       几个常用I/O函数:io.input ()、io.output ()、 io.read()、 io.write()

[plain] view plaincopy

  1. local file = assert(io.open(filename, “w”))

  2. if file ~= nil then

  3. file:write("hello lua!!!!")  --注意,等同于io.write("hello lua!!!!")

  4. file:close()  --等同于io.close(file)

  5. end

3、调试库

debug.getinfo()函数,他的第一个参数 可以是一个函数或一个栈层。返回结果是一个table,其中包含了函数的定义位置、行号、函数类型、函数名称等信息。

         debug.getlocal()函数检查函数任意局部变量,有两个参数,第一个是希望查询的函数栈层,另一个是变量的索引。

         assert(trunk)() 函数,执行参数中代码块并在出错时提供报错功能

[plain] view plaincopy

  1. a = "hello world"

  2. b = "print(a)"

  3. assert(loadstring(b))()

  4. --输出结果:

  5. hello world

4、几个处理Lua代码块的函数

 loadstring(pString)()函数可以直接执行pString字符串组成的Lua代码,但不提供报错功能

[plain] view plaincopy

  1. loadstring("for index = 1, 4 do print(\"for cycle index =\",index) end")()

  2. --[[

  3. 输出结果

  4. for cycle index =   1

  5. for cycle index =   2

  6. for cycle index =   3

  7. for cycle index =   4

  8. --]]

dofile(filename)函数的功能是载入并立刻执行Lua脚本文件。可以用来载入定义函数的文件或者数据文件、或立即执行的Lua代码。dofile函数会将程序的执行目录作为当前目录。如果要载入程序执行目录的子目录里的文件,需要加上子目录的路径。

[plain] view plaincopy

  1. dofile("/Users/ericli/WorkSpace/Lua语言/hellolua.lua")

  2. --输出结果:Hello Lua!

本篇总结完毕,本篇只是总结了Lua的一些最基本的语法。至于Lua的更高级的内容,比如:协同程序、模块与包、Lua调用C代码、C++与Lua的整合等,还需要在以后的学习过程中深入。

参考资料:

解决Lua语法缺失及替代措施

书籍:《Lua程序设计》、《Lua游戏开发实践指南》

Lua脚本之语法基础快速入门的更多相关文章

  1. Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 6. 条件

    前面的教程中,我们已经可以让小海龟绘制出各种图形了.但是,所有绘图的代码都是预先编好的,程序一旦运行起来,运行结果(绘制的图形)就是固定不变的.这一节中,咪博士将教大家如何让海龟响应用户的输入. im ...

  2. [易学易懂系列|rustlang语言|零基础|快速入门|(22)|宏Macro]

    [易学易懂系列|rustlang语言|零基础|快速入门|(22)|宏Macro] 实用知识 宏Macro 我们今天来讲讲Rust中强大的宏Macro. Rust的宏macro是实现元编程的强大工具. ...

  3. [易学易懂系列|rustlang语言|零基础|快速入门|(21)|智能指针]

    [易学易懂系列|rustlang语言|零基础|快速入门|(21)|智能指针] 实用知识 智能指针 我们今天来讲讲Rust中的智能指针. 什么是指针? 在Rust,指针(普通指针),就是保存内存地址的值 ...

  4. 序言 - PHP零基础快速入门

    我为什么要写<PHP零基础快速入门>? 原因: PHP 真心简单,适合零基础的人快速入门掌握,身边的人学习一两周上手开发的比比皆是: 市面上的文章或书籍对初学者并不友好,多半枯燥乏味,我相 ...

  5. 零基础快速入门web学习路线(含视频教程)

    下面小编专门为广大web学习爱好者汇总了一条完整的自学线路:零基础快速入门web学习路线(含视频教程)(绝对纯干货)适合初学者的最新WEB前端学习路线汇总! 在当下来说web前端开发工程师可谓是高福利 ...

  6. Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 7. 条件循环

    条件循环能够让程序在条件成立时(即为真时)重复执行循环体中的语句.如果条件一直成立(即永远不会为假),则循环会一直进行下去,不会停止.如果初始时,条件不成立,则循环 1 次也不会执行.Python 中 ...

  7. Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 5. 参数

    上一个教程中,咪博士带大家学习了函数的使用.例如,line_without_moving 函数,可以让海龟先画出一条线段,然后再回来起点. def line_without_moving(): tur ...

  8. Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 4. 函数

    什么样的程序员才是优秀的程序员?咪博士认为“慵懒”的程序员才是真正优秀的程序员.听起来不合逻辑?真正优秀的程序员知道如何高效地工作,而不是用不止境的加班来完成工作任务.函数便是程序员高效工作的利器之一 ...

  9. Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 3. 循环

    在前面的教程中,咪博士留了一道练习题给大家—-画正方形,相信聪明的你应该已经画出来了. 下面是咪博士实现的代码. 是不是跟你的代码很像呢? import turtle turtle.forward(2 ...

随机推荐

  1. iOS开发——开发技巧&LLDB详解

    开胃小菜--简单的断点调试 在xcode中打开一个app,在想要break的行号上单击,即可生成一个深色的箭头标识--断点.如下图,在viewDidLoad:中设置了断点. 运行app,等待...就可 ...

  2. HttpClient 4.3.* 上传带中文文件名文件文件名乱码问题的解决

    又是折腾了一天才解决的问题,网上关于这个问题的资料不多,希望写出来能帮到有需要的人. 之前无论怎么设置charset都不起作用, 后来看了这篇文章 才发现MultipartEntityBuilder有 ...

  3. PAT 1012

    1012. The Best Rank (25) To evaluate the performance of our first year CS majored students, we consi ...

  4. JavaScript标准Selection操作

    简介 术语 属性 方法 document.activeElement document.designMode = 'on'; 简介 selection是对当前激活选中区(即高亮文本)进行操作. 在非I ...

  5. 我的开发框架(WinForm)

    近来,看园子里,好多同学,展示自己工作中的开发框架,有的功能强大,有的短小精悍,我也来凑个热闹,望各位大侠指点一二. 一.指导思想 1.尽量减少程序员对数据库的依赖,或者说尽力少的写sql 语句.根据 ...

  6. 【并查集】PKU-1182 食物链

    食物链 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不 ...

  7. [记录]gulp compass

    因为个人习惯用compass,所以gulp中,还是用compass进行编译scss文件. 1. 使用npm安装gulp-compass npm install gulp-compass --save- ...

  8. nginx支持url的PATHINFO

    fastcgi_split_path_info ^(.+?\.php)(/.*)$; set $path_info $fastcgi_path_info; fastcgi_param PATH_INF ...

  9. js运动

    一.offsetWidth / offsetHeight 获取整个块的宽度/高度,包括border 二.clientWidth / clientHeight 获取块的宽度/高度,不包括border 三 ...

  10. 正则表达式 自学笔记整理记录 EASY REGEX~

    整理正则表达式篇                             -wuian7yulian 基础知识介绍 :  1> 字符串的组成: 对于字符串"ABC"来说,其包 ...