Lua脚本
•
编程语言
1.准备
1.简介
- 1.Lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放
2.目标
- 1.其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能
3.特点
- 1.轻量级:用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可方便嵌入别的程序里
- 2.可扩展:Lua提供易于使用的扩展接口和机制:由宿主语言(C/C++)提供这些功能,Lua可像内置功能一样使用
- 3.支持面向过程(procedure-oriented)编程和函数式编程(functional programming)
- 4.自动内存管理,只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象
- 5.语言内置模式匹配;闭包(closure);函数也可以看做一个值;提供多线程(协同进程,并非操作系统所支持的线程)支持
- 6.通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承和重载等
4.应用场景
- 1.游戏开发
- 2.独立应用脚本
- 3.Web应用脚本
- 4.扩展和数据库插件(MySQL Proxy 和 MySQL WorkBench)
- 5.安全系统(入侵检测系统)
5.环境安装
1.Linux系统
curl -R -O http://www.lua.org/ftp/lua-5.3.0.tar.gz tar zxf lua-5.3.0.tar.gz cd lua-5.3.0 make linux test make install
2.Mac系统
curl -R -O http://www.lua.org/ftp/lua-5.3.0.tar.gz tar zxf lua-5.3.0.tar.gz cd lua-5.3.0 make macosx test make install
3.Window系统
- 1.进入Lua官网:http://www.lua.org
- 2.点击download
- 3.选择二进制文件
- 4.点击左边的Download并选择对应版本lua-5.4.2_Win64_bin.zip进行下载
- 5.将对应压缩包解压到指定文件
- 6.配置环境变量
- 7.进入cmd进行测试
2.基础
1.交互式编程
- 1.默认使用交互式编程
- 2.交互式编程可以输入程序并立即查看结果
2.脚本式编程
- 1.将Lua程序保存到一个以lua结尾的文件并执行
- 2.如果Lua脚本文件有错误则内容都不会执行
3.注释
1.单行注释
--print("Hello World")print("Hello Lua")
2.多行注释
--[[ 多行注释 多行注释 --]]
4.标示符
- 1.Lua标示符用于定义一个变量,函数获取其他用户定义的项
- 2.标示符以一个字母 A-Z 或 a-z 或下划线 _ 开头,然后加上 0 个或多个字母,下划线,数字(0-9)
- 3.Lua不允许使用特殊字符( @、$、% )定义标示符
- 4.不推荐使用下划线加大写字母的标示符,因为Lua的保留字也是这样
- 5.一般约定以下划线开头连接一串大写字母的名字( _VERSION)被保留用于Lua内部全局变量
- 6.Lua是一个区分大小写的编程语言,因此Lua中Runoob与runoob是两个不同的标示符
5.关键字
- 1.Lua保留关键字不能作为常量或变量或其他用户自定义标示符
and break do else elseif end false for function if in local nil not or repeat return then true until while goto
6.全局变量
- 1.默认情况下,变量总是认为是全局的
- 2.全局变量不需要声明,给一个变量赋值后即创建了这个全局变量
- 3.访问一个没有初始化的全局变量不会出错,只是得到的结果是nil
- 4.如果想删除一个全局变量,只需要将变量赋值为nil;当且仅当一个变量不等于nil时,这个变量即存在
3.数据类型
1.Lua是动态类型语言,变量不要类型定义,只需要为变量赋值
2.值可以存储在变量中,作为参数传递或结果返回
3.Lua可以使用type函数测试给定变量或者值的类型
4.Lua中有8个基本类型
数据类型 描述 nil 只有值nil属于该类,表示一个无效值(在条件表达式中相当于false) boolean false和true number 表示双精度类型的实浮点数 string 字符串由一对双引号或单引号来表示 function 由C或Lua编写的函数 userdata 表示任意存储在变量中的C数据结构 thread 表示执行的独立线路,用于执行协同程序 table Lua中的表table其实是一个关联数组associative arrays;数组的索引可以是数字、字符串或表类型;Lua中table 的创建是通过构造表达式来完成,最简单构造表达式是{},用来创建一个空表
1.nil(空)
1.nil类型表示没有任何有效值,它只有一个值nil
2.打印一个没有赋值的变量,便会输出一个nil值
3.对于全局变量和table,nil还有一个删除作用,将全局变量或table表里的变量赋nil值等同于删除
4.nil作比较时应该加上双引号(type(X)==nil 结果为 false 的原因是 type(X) 实质是返回的nil字符串是一个 string 类型)
2.boolean(布尔)
- 1.boolean类型只有两个可选值:true(真) 和 false(假)
- 2.Lua把false和nil看作是false,其他的都为true,数字0也是true
3.number(数字)
- 1.Lua默认只有一种number类型 -> double(双精度)类型(默认类型可以修改luaconf.h里的定义)
4.string(字符串)
- 1.字符串由一对双引号或单引号来表示
- 2.或者使用2个方括号[[]]来表示一块字符串
- 3.对一个数字字符串进行算术操作时,Lua会尝试将该数字字符串转换成一个数字
- 4.字符串连接使用的是 ..
- 5.使用#计算字符串的长度并且放在字符串前面
5.table(表)
- 1.Lua中table的创建是通过构造表达式来完成,最简单构造表达式是{},用来创建一个空表
- 2.table也可以创建时在表里添加数据直接初始化表
- 3.Lua中的表table其实是一个关联数组associative arrays,数组的索引可以是数字或字符串(表类似集合)
- 4.如果遍历则第一个参数默认为索引,第二个参数为value
- 5.不同于其他语言的数组把0作为数组的初始索引,Lua 中表的默认初始索引以1开始
- 6.table不会固定长度大小,有新数据添加时table长度会自动增长(注意:#只能统计索引为数字的长度),没初始的table都是nil
6.function(函数)
- 1.Lua中函数被看作是第一类值First-Class Value,函数可以存在变量中
- 2.function可以以匿名函数anonymous function的方式通过参数传递
7.thread(线程)
- 1.Lua中最主要的线程是协同程序coroutine
- 2.类似线程thread,拥有自己独立的栈、局部变量和指令指针
- 3.可以跟其他协同程序共享全局变量和其他大部分东西
- 4.线程跟协程的区别:线程可以同时多个运行,而协程任意时刻只能运行一个,并且处于运行状态的协程只有被挂起suspend时才会暂停
8.userdata(自定义类型)
- 1.userdata是一种用户自定义数据,用于表示一种由应用程序或C/C++语言库所创建的类型
- 2.其可以将任意C/C++的任意数据类型的数据(通常是 struct 和 指针)存储到Lua变量中调用
4.变量
- 1.变量在使用前需要在代码中进行声明,即创建该变量
- 2.编译程序执行代码之前编译器需要知道如何给语句变量开辟存储区,其用于存储变量的值
- 3.Lua变量有三种类型
- 1.全局变量
- 2.局部变量
- 3.表中的域
- 4.变量的默认值均为nil
1.全局变量
- 1.Lua中的变量全是全局变量,哪怕是语句块或是函数里,除非用local显式声明为局部变量
- 2.Lua语言中,全局变量无须声明即可使用,使用未经初始化的全局变量不会导致错误
- 3.当使用未经初始化的全局变量时,得到的结果为nil
2.局部变量
- 1.只有使用local显式声明的才是局部变量
- 2.局部变量的作用域为从声明位置开始到所在语句块结束
- 3.尽可能的使用局部变量,有两个好处
- 1.避免命名冲突
- 2.访问局部变量的速度比全局变量更快
3.变量赋值
- 1.Lua可对多个变量同时赋值,变量列表和值列表的各个元素用逗号分开,赋值语句右边的值会依次赋给左边的变量
- 2.遇到赋值语句Lua会先计算右边所有的值然后再执行赋值操作,所以可以快捷交换变量的值
- 3.当变量个数和值的个数不一致时,Lua会一直以变量个数为基础采取以下策略
- 1.变量个数 > 值的个数 -> 按变量个数补足nil
- 2.变量个数 多余的值会被忽略
- 4.如果要对多个变量赋值必须依次对每个变量赋值
- 5.多值赋值经常用来交换变量,或将函数调用返回给变量
- 6.Lua对多个变量同时赋值,不会进行变量传递,仅做值传递
5.循环
- 1.循环结构是在一定条件下反复执行某段程序的流程结构,被反复执行的程序被称为循环体
- 2.循环语句是由循环体及循环的终止条件两部分组成的
1.while循环
while(condition)do statementsend
- 1.Lua中while循环语句在判断条件为true时会重复执行循环体语句
- 2.statements(循环体语句) 可以是一条或多条语句,condition(条件) 可以是任意表达式,当 condition(条件) 为true时执行循环体语句
2.for循环
- 1.Lua中for循环语句可以重复执行指定语句,重复次数可在for语句中控制
- 2.Lua编程语言中for语句有两大类
- 1.数值for循环
- 2.泛型for循环
1.数值for循环
for var=exp1,exp2,exp3 do end
- 1.var从exp1变化到exp2,每次变化以exp3为步长递增var,并执行一次 执行体
- 2.其中exp3是可选的,如果不指定则默认值为1
- 3.for的三个表达式在循环开始前一次性求值(例:函数f(x)只在循环开始前执行一次),以后不再进行求值
2.泛型for循环
--打印数组a的所有值 a = {"one", "two", "three"}for i, v in ipairs(a) do print(i, v)end
- 1.泛型for循环通过一个迭代器函数来遍历所有值,类似java中的foreach语句
- 2.i是数组索引值,v是对应索引的数组元素值。ipairs是Lua提供的一个迭代器函数,用来迭代数组
3.repeat…until循环
repeat statementsuntil( condition )
- 1.Lua中repeat…until循环语句不同于for和while循环
- 2.for和while循环的条件语句在当前循环执行开始时判断,而 repeat…until循环的条件语句在当前循环结束后判断
- 3.因为循环条件判断语句condition在循环体末尾部分,所以在条件进行判断前循环体都会执行一次
- 4.如果条件判断语句condition为 false,循环会重新开始执行,直到条件判断语句condition为true才会停止执行
4.嵌套循环
for init,max/min value, incrementdo for init,max/min value, increment do statements end statementsendwhile(condition)do while(condition) do statements end statementsendrepeat statements repeat statements until( condition )until( condition )
5.break语句
- 1.Lua中break语句插入在循环体中,用于退出当前循环或语句,并开始执行紧接着的语句
- 2.如果你使用循环嵌套,break语句将停止最内层循环的执行,并开始执行的外层的循环语句
6.goto语句
goto Label-- Label 的格式:: Label ::
- 1.Lua中的goto语句允许将控制流程无条件地转到被标记的语句处
- 2.lable中可以设置多个语句
- 3.使用goto可以实现continue的功能
6.流程控制
- 1.Lua控制语句通过程序设定一个或多个条件语句,条件为true时执行指定程序代码,条件为false时执行其他指定代码
- 2.控制结构的条件表达式结果可以是任何值,Lua认为false和nil为假,true和非nil为真,且Lua中0为true
1.if语句
if(布尔表达式)then --[ 在布尔表达式为 true 时执行的语句 --]end--[ 定义变量 --]a = 10;--[ 使用 if 语句 --]if( a < 20 )then --[ if 条件为 true 时打印以下信息 --] print("a 小于 20" );endprint("a 的值为:", a);
2.if…else语句
if(布尔表达式)then --[ 布尔表达式为 true 时执行该语句块 --]else --[ 布尔表达式为 false 时执行该语句块 --]end-------------------------------------------------------if( 布尔表达式 1)then --[ 在布尔表达式 1 为 true 时执行该语句块 --]elseif( 布尔表达式 2)then --[ 在布尔表达式 2 为 true 时执行该语句块 --]elseif( 布尔表达式 3)then --[ 在布尔表达式 3 为 true 时执行该语句块 --]else --[ 如果以上布尔表达式都不为 true 则执行该语句块 --]end--[ 定义变量 --]a = 100;--[ 检查条件 --]if( a < 20 )then --[ if 条件为 true 时执行该语句块 --] print("a 小于 20" )else --[ if 条件为 false 时执行该语句块 --] print("a 大于 20" )endprint("a 的值为 :", a)--[ 定义变量 --]a = 100--[ 检查布尔条件 --]if( a == 10 )then --[ 如果条件为 true 打印以下信息 --] print("a 的值为 10" )elseif( a == 20 )then --[ if else if 条件为 true 时打印以下信息 --] print("a 的值为 20" )elseif( a == 30 )then --[ if else if condition 条件为 true 时打印以下信息 --] print("a 的值为 30" )else --[ 以上条件语句没有一个为 true 时打印以下信息 --] print("没有匹配 a 的值" )endprint("a 的真实值为: ", a )
3.if 嵌套语句
if( 布尔表达式 1)then --[ 布尔表达式 1 为 true 时执行该语句块 --] if(布尔表达式 2) then --[ 布尔表达式 2 为 true 时执行该语句块 --] endend--[ 定义变量 --]a = 100;b = 200;--[ 检查条件 --]if( a == 100 )then --[ if 条件为 true 时执行以下 if 条件判断 --] if( b == 200 ) then --[ if 条件为 true 时执行该语句块 --] print("a 的值为 100 b 的值为 200" ); endendprint("a 的值为 :", a );print("b 的值为 :", b );
7.函数
- 1.Lua提供内建函数,可方便的在程序中调用(print()函数可将传入的参数打印在控制台)
- 2.Lua函数主要有两种用途
- 1.完成指定的任务:该情况函数作为调用语句使用
- 2.计算并返回值:该情况函数作为赋值语句的表达式使用
- 3.Lua中可以将函数作为参数传递给函数
1.定义
[optional_function_scope] function function_name( argument1, argument2..., argumentn) function_body return result_params_comma_separatedend
- 1.optional_function_scope:可选参数,指定函数是全局函数还是局部函数,默认全局函数,设置函数为局部函数需要使用关键字local
- 2.function_name:指定函数名称
- 3.argument1, argument2…, argumentn:函数参数,多个参数以逗号隔开,函数可不带参数
- 4.function_body:函数体,函数中需要执行的代码语句块
- 5.result_params_comma_separated:函数返回值,Lua语言函数可返回多个值,每个值以逗号隔开
2.多返回值
- 1.Lua函数可以返回多个结果值,在return后列出要返回的值的列表即可返回多值
-- 例:string.find,其返回匹配串开始和结束的下标,如果不存在匹配串返回nil s, e = string.find("www.runoob.com", "runoob") print(s, e)
3.可变参数
- 1.Lua函数可接受可变数目的参数,函数参数列表中使用三点…表示函数有可变的参数
- 2.Lua将可变参数赋值给一个变量,通过#可变参数可获取可变参数的数量,也可通过 select(“#”,参数)来获取可变参数的数量
- 1.通常遍历可变参数时只需要使用 {…}
- 2.然而可变参数可能会包含nil,此时可以用select函数来访问可变参数
- 3.调用select时,必须传入一个固定实参selector(选择开关) 和变长参数
- 4.如果selector为数字n,那么select返回参数列表中从索引n开始到结束位置的所有参数列表
- 5.否则只能为字符串#,这样select返回可变参数的总数
- 1.select(‘#’, …) :返回可变参数的长度
- 2.select(n, …) :返回从起点n开始到结束位置的所有参数列表
- 3.如果同时存在固定参数和可变参数,则固定参数必须放在可变参数之前
8.运算符
- 1.Lua提供了以下几种运算符类
- 1.算术运算符
- 2.关系运算符
- 3.逻辑运算符
- 4.其他运算符
1.算术运算符
操作符 描述 实例 + 加法 A=10,B=20;A+B=30 – 减法 A=10,B=20;A-B=-10 * 乘法 A=10,B=20;A*B=200 / 除法 A=10,B=20;B/A=2 % 取余 A=10,B=20;B%A=0 ^ 乘幂 A=10,B=20;A^2=100 – 负号 A=10,B=20;-A=-10 // 整除运算符(版本>=lua5.3) A=10,B=20;5//2=2
- 1.lua中/ 用作除法运算:计算结果包含小数部分;// 用作整除运算:计算结果不包含小数部分
2.关系运算符
操作符 描述 实例 == 等于,检测两个值是否相等,相等返回 true,否则返回 false A=10,B=20;(A == B) 为 false ~= 不等于,检测两个值是否相等,不相等返回 true,否则返回 false A=10,B=20;(A ~= B) 为 true > 大于,如果左边的值大于右边的值,返回 true,否则返回 false A=10,B=20;(A > B) 为 false < 小于,如果左边的值大于右边的值,返回 false,否则返回 true A=10,B=20;(A < B) 为 true >= 大于等于,如果左边的值大于等于右边的值,返回 true,否则返回 false A=10,B=20;(A >= B) 返回 false <= 小于等于, 如果左边的值小于等于右边的值,返回 true,否则返回 false A=10,B=20;(A <= B) 返回 true
3.逻辑运算符
操作符 描述 实例 and 逻辑与操作符。 若 A 为 false,则返回 A,否则返回 B A=true,B=false;(A and B) 为 false or 逻辑或操作符。 若 A 为 true,则返回 A,否则返回 B A=true,B=false;(A or B) 为 true not 逻辑非操作符。与逻辑运算结果相反,如果条件为 true,逻辑非为 false A=true,B=false;not(A and B) 为 true
4.其他运算符
操作符 描述 实例 .. 连接两个字符串 a…b ,a=”Hello ” , b =“World”, 输出结果为 “Hello World” # 一元运算符,返回字符串或表的长度 #“Hello” 返回 5
- 1.Lua中#是一个一元运算符,用于获取一个序列或字符串的长度,可以用于以下类型:
- 1.字符串:返回字符串的长度
- 2.数组:返回数组中元素的个数
- 3.table:返回table中的元素个数,不包括nil值
local str = "hello world" print(#str) -- 输出 11 local arr = {1, 2, 3, 4, 5} print(#arr) -- 输出 5 local tbl = {a = 1, b = 2, c = 3} print(#tbl) -- 输出 0,因为table中没有序列部分- 2.注意
- 1.对于table类型,#只能用于获取序列部分的长度,如果table中有非序列部分的元素,#将无法正确计算长度
- 2.#只能用于连续的整数序列,如果序列中间有nil值,#将返回第一个nil值之前的元素个数
- 3.对于字符串类型#只能正确返回ASCII类型字符,如果包含中文则结果会有问题,其中一个中文汉字占用3个字符长度
5.转义字符
转义字符 意义 ASCII码值(十进制) \a 响铃(BEL) 007 \b 退格(BS) ,将当前位置移到前一列 008 \f 换页(FF),将当前位置移到下页开头 012 \n 换行(LF) ,将当前位置移到下一行开头 010 \r 回车(CR) ,将当前位置移到本行开头 013 \t 水平制表(HT) (跳到下一个TAB位置) 009 \v 垂直制表(VT) 011 \\ 代表一个反斜线字符’\’ 092 ’ 代表一个单引号(撇号)字符 039 “ 代表一个双引号字符 034 \0 空字符(NULL) 000 \a 响铃(BEL) 007 \ddd 1到3位八进制数所代表的任意字符 三位八进制 \xhh 1到2位十六进制所代表的任意字符 二位十六进制
6.运算符优先级
9.字符串
- 1.字符串或串(String)是由数字、字母、下划线组成的一串字符
- 2.Lua中字符串是一种基本的数据类型,用于存储文本数据
- 3.Lua中的字符串可包含任意字符,包括字母、数字、符号、空格以及其他特殊字符
- 4.Lua中字符串可以使用以下三种方式来表示
- 1.单引号间的一串字符
local str1 = 'This is a string.' local str2 = "This is also a string."
- 2.双引号间的一串字符
local str = "Hello, " str = str .. "World!" -- 创建一个新的字符串并将其赋值给str print(str) -- 输出 "Hello, World!"
- 3.[[ 与 ]] 间的一串字符
local multilineString = [[ This is a multiline string. It can contain multiple lines of text. No need for escape characters. ]] print(multilineString)
1.字符串长度
- 1.Lua中要计算字符串的长度(即字符串中字符的个数),可使用 string.len或utf8.len函数或#字符
- 2.包含中文的一般用utf8.len,string.len函数用于计算只包含ASCII字符串的长度,其中#类似string.len
2.字符串操作
方法 用途 string.upper(argument) 字符串全部转为大写字母 string.lower(argument) 字符串全部转为小写字母 string.gsub(mStr,fStr,rStr,num) 字符串替换:mStr为要操作的字符串,fStr为被替换的字符,rStr要替换的字符,num 替换次数(可以忽略,则全部替换) string.find(str, substr, [init, [plain]]) 目标字符串str中搜索指定内容substr,如果找到匹配的子串返回子串的起始和结束索引,不存在则返回nil;init指定搜索起始位置,默认为 1,可使用负数,表示从后往前数的字符个数;plain表示是否使用简单模式,默认为false,true只做简单的查找子串的操作,false表示使用使用正则模式匹配 string.reverse(arg) 字符串反转 string.format(…) 返回一个类似printf的格式化字符串 string.char(arg) 和 string.byte(arg[,int]) char将整型数字转成字符并连接,byte转换字符为整数值(可以指定某个字符,默认第一个字符) string.len(arg) 计算字符串长度 string.rep(string, n) 返回字符串string的n个拷贝 .. 链接两个字符串 string.gmatch(str, pattern) 返回一个迭代器函数,每一次调用这个函数返回一个在字符串str找到的下一个符合pattern描述的子串;如果参 pattern描述的字符串没有找到,迭代函数返回nil string.match(str, pattern, init) 只寻找源字串str中的第一个配对,参数init可选, 指定搜寻过程的起点, 默认为1;成功配对时, 函数将返回配对表达式中的所有捕获结果; 如果没有设置捕获标记, 则返回整个配对字符串. 当没有成功的配对时, 返回nil string.sub(s, i [, j]) 字符串截取:s要截取的字符串,i截取开始位置,j截取结束位置,默认为 -1,最后一个字符
3.字符串格式化
- 1.Lua提供string.format()函数来生成具有特定格式的字符串, 函数的第一个参数是格式 , 之后是对应格式中每个代号的各种数据
- 2.由于格式字符串的存在, 使得产生的长字符串可读性提高
- 3.格式字符串可能包含以下的转义码
方法 用途 %c 接受一个数字, 并将其转化为ASCII码表中对应的字符 %d、%i 接受一个数字并将其转化为有符号的整数格式 %o 接受一个数字并将其转化为八进制数格式 %u 接受一个数字并将其转化为无符号整数格式 %x 接受一个数字并将其转化为十六进制数格式, 使用小写字母 %X 接受一个数字并将其转化为十六进制数格式, 使用大写字母 %e 接受一个数字并将其转化为科学记数法格式, 使用小写字母e %E 接受一个数字并将其转化为科学记数法格式, 使用大写字母E %f 接受一个数字并将其转化为浮点数格式 %g(%G) 接受一个数字并将其转化为%e(%E, 对应%G)及%f中较短的一种格式 %q 接受一个字符串并将其转化为可安全被Lua编译器读入的格式 %s 接受一个字符串并按照给定的参数格式化该字符串 - 4.格式%后可添加参数
- 1.符号:一个+号表示其后的数字转义符将让正数显示正号,默认情况下只有负数显示符号
- 2.占位符:一个0后面指定字符串宽度占用符,不填的默认占用符是空格
- 3.对齐标识:指定字符串宽度时,默认为右对齐,增加-号可以改为左对齐
- 4.小数位
- 1.宽度数值后增加的小数部分n, 若后接f(浮点数转义符, 如%6.3f)则设定该浮点数的小数只保留n位
- 2.若后接s(字符串转义符, 如%5.3s)则设定该字符串只显示前n位
string1 = "Lua" string2 = "Tutorial" number1 = 10 number2 = 20 -- 基本字符串格式化 print(string.format("基本格式化 %s %s",string1,string2)) -- 日期格式化 date = 2; month = 1; year = 2014 print(string.format("日期格式化 %02d/%02d/%03d", date, month, year)) -- 十进制格式化 print(string.format("%.4f",1/3)) -- 执行结果 基本格式化 Lua Tutorial 日期格式化 02/01/2014 0.3333string.format("%c", 83) -- 输出S string.format("%+d", 17.0) -- 输出+17 string.format("%05d", 17) -- 输出00017 string.format("%o", 17) -- 输出21 string.format("%u", 3.14) -- 输出3 string.format("%x", 13) -- 输出d string.format("%X", 13) -- 输出D string.format("%e", 1000) -- 输出1.000000e+03 string.format("%E", 1000) -- 输出1.000000E+03 string.format("%6.3f", 13) -- 输出13.000 string.format("%q", "One\nTwo") -- 输出"One\ -- Two" string.format("%s", "monkey") -- 输出monkey string.format("%10s", "monkey") -- 输出 monkey string.format("%5.3s", "monkey") -- 输出 mon
4.字符与整数相互转换
-- 字符转换 -- 转换第一个字符 print(string.byte("Lua")) -- 转换第三个字符 print(string.byte("Lua",3)) -- 转换末尾第一个字符 print(string.byte("Lua",-1)) -- 第二个字符 print(string.byte("Lua",2)) -- 转换末尾第二个字符 print(string.byte("Lua",-2)) -- 整数 ASCII 码转换为字符 print(string.char(97))
5.匹配模式
- 1.Lua中的匹配模式直接用常规的字符串来描述
- 2.Lua用于模式匹配函数
- 1.string.find
- 2.string.gmatch
- 3.string.gsub
- 4.string.match
- 3.模式串中可以使用字符类,字符类指可以匹配一个特定字符集合内任意字符的模式项
10.数组
- 1.Lua中数组不是一种特定的数据类型,而是一种用来存储一组值的数据结构
- 2.实际Lua中并没有专门的数组类型,而是使用table数据结构实现数组的功能
- 3.Lua中数组得索引键值可使用整数表示,数组的大小不是固定的
- 4.Lua数组索引值默认是以1为起始,可指定从0开始,也可以以负数为数组索引,如果指定的索引没有值则返回nil
1.一维数组
2.多维数组
- 1.多维数组:即数组中包含数组或一维数组的索引键对应一个数组
11.迭代器
- 1.迭代器iterator是一种对象,用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址
- 2.Lua中迭代器是一种支持指针类型的结构,可遍历集合的每一个元素
- 3.Lua中常使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素,Lua的迭代器包含以下两种类型
- 1.无状态的迭代器
- 2.多状态的迭代器
1.泛型for迭代器
-- k,v为变量列表;pairs(t)为表达式列表for k, v in pairs(t) do print(k, v) end
- 1.泛型for在内部保存迭代函数,实际上它保存三个值
- 1.迭代函数
- 2.状态常量
- 3.控制变量
- 2.泛型for执行流程
- 1.初始化计算in后面表达式的值,表达式应该返回泛型for 需要的三个值,与多值赋值一样,如果表达式返回的结果个数不足三个会自动用nil补足,多出部分会被忽略
- 1.迭代函数
- 2.状态常量
- 3.控制变量
- 2.将状态常量和控制变量作为参数调用迭代函数(注意:对于for结构来说,状态常量没有用处,仅仅在初始化时获取值并传递给迭代函数)
- 3.将迭代函数返回的值赋给变量列表
- 4.如果返回的第一个值为nil循环结束,否则执行循环体
- 5.回到第二步再次调用迭代函数
2.无状态迭代器
- 1.无状态的迭代器:指不保留任何状态的迭代器,因此在循环中可以利用无状态迭代器避免创建闭包花费额外的代价。
- 2.每一次迭代,迭代函数都是用两个变量(状态常量和控制变量)的值作为参数被调用,一个无状态的迭代器只利用这两个值可以获取下一个元素。
- 3.这种无状态迭代器的典型的简单的例子是ipairs,它遍历数组的每一个元素,元素的索引需要是数值
function square(iteratorMaxCount,currentNumber) if currentNumber<iteratorMaxCount then currentNumber = currentNumber+1 return currentNumber, currentNumber*currentNumber endendfor i,n in square,3,0do print(i,n)end- 4.迭代的状态包括被遍历的表(循环过程中不会改变的状态常量)和当前的索引下标(控制变量),ipairs和迭代函数简单,在Lua中实现
function iter (a, i) i = i + 1 local v = a[i] if v then return i, v end`在这里插入代码片`endfunction ipairs (a) return iter, a, 0end- 1.当Lua调用ipairs(a)开始循环时,他获取三个值:迭代函数iter,状态常量a,控制变量初始值0;
- 2.然后
3.多状态迭代器
12.table(表)
- 1.Lua中的table是一种数据结构,用来创建数组,字典等
- 2.Lua中的table使用关联型数组,可用任意类型的值作为数组的索引,但是不能为nil
- 3.Lua中的table的大小不是固定的,可以根据需要进行扩容
- 4.Lua通过table处理模块(module)、包(package)和对象(object)
1.table的构造
- 1.构造器是创建和初始化表的表达式
- 2.最简单的构造函数是{},用来创建一个空表
-- 初始化表mytable = {}-- 指定值mytable[1]= "Lua"-- 移除引用mytable = nil-- lua 垃圾回收会释放内存- 3.初始化table A并设置元素,然后将A赋值给B,则A和B都指向同一个内存
- 4.如果A设置为nil,则B同样可以访问table元素,如果没有指定的变量指向A,则Lua的垃圾回收机制会清理相对应的内存
-- 简单的 tablemytable = {}print("mytable 的类型是 ",type(mytable))mytable[1]= "Lua"mytable["wow"] = "修改前"print("mytable 索引为 1 的元素是 ", mytable[1])print("mytable 索引为 wow 的元素是 ", mytable["wow"])-- alternatetable和mytable的是指同一个 tablealternatetable = mytableprint("alternatetable 索引为 1 的元素是 ", alternatetable[1])print("mytable 索引为 wow 的元素是 ", alternatetable["wow"])alternatetable["wow"] = "修改后"print("mytable 索引为 wow 的元素是 ", mytable["wow"])-- 释放变量alternatetable = nilprint("alternatetable 是 ", alternatetable)-- mytable 仍然可以访问print("mytable 索引为 wow 的元素是 ", mytable["wow"])mytable = nilprint("mytable 是 ", mytable)-- 执行结果mytable 的类型是 tablemytable 索引为 1 的元素是 Luamytable 索引为 wow 的元素是 修改前alternatetable 索引为 1 的元素是 Luamytable 索引为 wow 的元素是 修改前mytable 索引为 wow 的元素是 修改后alternatetable 是 nilmytable 索引为 wow 的元素是 修改后mytable 是 nil
2.table的操作
方法 用途 able.concat (table [, sep [, start [, end]]]): concat是concatenate(连锁, 连接)的缩写. table.concat()函数列出参数中指定table的数组部分从start位置到end位置的所有元素, 元素间以指定的分隔符(sep)隔开 table.insert (table, [pos,] value): 在table的数组部分指定位置(pos)插入值为value的一个元素. pos参数可选, 默认为数组部分末尾
13.模块与包
- 1.模块类似于一个封装库,从Lua 5.1开始Lua加入了标准的模块管理机制
- 2.模块可把一些公用的代码放在一个文件里,以API接口的形式在其他地方调用,有利于代码的重用和降低代码耦合度
- 3.Lua的模块是由变量、函数等已知元素组成的table
- 4.因此创建一个模块很简单,就是创建一个table,然后把需要导出的常量、函数放入其中,最后返回这个table就行
- 5.模块的结构就是一个table的结构,因此可以像操作调用table里的元素那样来操作调用模块里的常量或函数
- 6.可使用local声明变量为程序块的局部变量,即表示一个私有函数,因此是不能从外部访问模块里的这个私有函数,必须通过模块里的公有函数来调用
1.require函数
- 1.Lua提供了一个require的函数用来加载模块
- 2.执行require后会返回一个由模块常量或函数组成的table,并且还会定义一个包含该table的全局变量
- 3.其中require中引用的是Lua的文件名,而不是模块名,全局变量引用的是模块名,而不是文件名
- 4.可以加载的模块定义一个别名变量方便调用
3.加载机制
- 1.对于自定义的模块,模块文件不是放在哪个文件目录都行,函数 require 有自己的文件路径加载策略
- 2.其会尝试从Lua文件或C程序库中加载模块
- 3.require用于搜索Lua文件的路径是存放在全局变量package.path 中
- 4.当Lua启动后会以环境变量LUA_PATH的值来初始这个环境变量
- 5.如果没有找到该环境变量,则使用一个编译时定义的默认路径来初始化
- 6.如果找到目标文件,则会调用package.loadfile来加载模块,否则就会去找C程序库
- 7.搜索的文件路径是从全局变量 package.cpath获取,而这个变量则是通过环境变量LUA_CPATH`来初始
- 8.搜索策略跟上面的一样,只不过现在换成搜索的是so或dll类型的文件,如果找到那么require会通过package.loadlib来加载
14.元表(Metatable)
15.协同程序(coroutine)
16.文件I/O
17.错误处理
18.调试(Debug)
19.垃圾回收
20.面向对象
21.数据库访问
本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://www.net2asp.com/7ccada9fb4.html








































































































