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系统
bashcurl -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系统
bashcurl -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.单行注释
lua--print("Hello World") print("Hello Lua")
2.多行注释
lua--[[ 多行注释 多行注释 --]]
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循环
luawhile(condition) do statements end
- 1.
Lua
中while
循环语句在判断条件为true
时会重复执行循环体语句- 2.
statements
(循环体语句) 可以是一条或多条语句,condition
(条件) 可以是任意表达式,当condition
(条件) 为true
时执行循环体语句
2.for循环
- 1.
Lua
中for
循环语句可以重复执行指定语句,重复次数可在for
语句中控制- 2.
Lua
编程语言中for
语句有两大类
- 1.数值
for
循环- 2.泛型
for
循环1.数值for循环
luafor var=exp1,exp2,exp3 do <执行体> end
- 1.
var
从exp1
变化到exp2
,每次变化以exp3
为步长递增var
,并执行一次执行体
- 2.其中
exp3
是可选的,如果不指定则默认值为1
- 3.
for
的三个表达式在循环开始前一次性求值(例:函数f(x)
只在循环开始前执行一次),以后不再进行求值
2.泛型for循环
lua--打印数组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循环
luarepeat statements until( condition )
- 1.
Lua
中repeat...until
循环语句不同于for
和while
循环- 2.
for
和while
循环的条件语句在当前循环执行开始时判断,而repeat...until
循环的条件语句在当前循环结束后判断- 3.因为循环条件判断语句
condition
在循环体末尾部分,所以在条件进行判断前循环体都会执行一次- 4.如果条件判断语句
condition
为false
,循环会重新开始执行,直到条件判断语句condition
为true
才会停止执行
4.嵌套循环
luafor init,max/min value, increment do for init,max/min value, increment do statements end statements end
luawhile(condition) do while(condition) do statements end statements end
luarepeat statements repeat statements until( condition ) until( condition )
5.break语句
- 1.
Lua
中break
语句插入在循环体中,用于退出当前循环或语句,并开始执行紧接着的语句- 2.如果你使用循环嵌套,
break
语句将停止最内层循环的执行,并开始执行的外层的循环语句
6.goto语句
luagoto 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语句
2.if...else语句
3.if 嵌套语句
模块与包
- 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
来加载