数据类型
数据类型 | 描述 |
---|---|
nil | 只有值nil 属于该类,表示一个无效值(在条件表达式中相当于false)。 |
boolean | 包含两个值:false 和true 。 |
number | 表示双精度类型的实浮点数 |
string | 字符串由一对双引号或单引号来表示 |
function | 由 C 或 Lua 编写的函数 |
userdata | 表示任意存储在变量中的C数据结构 |
thread | 表示执行的独立线路,用于执行协同程序 |
table | Lua 中的表(table )其实是一个"关联数组",数组的索引可以是数字、字符串或表类型。 |
Lua
是动态类型语言,变量不需要定义
nil
表示一种没有任何有效值,没有赋值的变量值为
nil
a
print(a) -- nil
a=1
print(a) -- 1
对于全局变量和表,nil还有删除作用,给全局变量和table表里的变量赋一个值,等同于把他们删除掉
tab1 = { key1 = "val1", key2 = "val2"}
for k, v in pairs(tab1) do
print(k .. " - " .. v)
end
print("删除key1")
tab1.key1 = nil
for k, v in pairs(tab1) do
print(k .. " - " .. v)
end
--[=[ 结果
key1 - val1
key2 - val2
删除key1
key2 - val2
--]=]
type
函数返回的是字符串,nil
做比较时要加上双引号直接比较不用加双引号
> print(x == nil)
true
> print(type(X)==nil)
false
> print(type(X)=="nil")
true
boolean
布尔
只有两个值:
true
和false
在
Lua
中只有false
和nil
是假值,其他都是真值,数字0也是真值
number
数字
Lua
中number
类型是double
(双精度)类型整数、小数都是
number
类型
string
字符串
用双引号、单引号来表示
print("this is string!")
print('this is string!')
使用
[[]]
来表示一块字符串
blockStr = [[
床前明月光,
疑是地上霜。
举头望明月,
低头思故乡。
]]
print(blockStr)
在对一个数字字符串上进行算术操作时,Lua 会尝试将这个数字字符串转成一个数字
> print("2" + 6)
8
> print("2" + "6")
8
print("2 + 6")
2 + 6
字符串连接使用
..
,两个点
> print("a" .. "b")
ab
> print(123 .. 456)
123456
使用
#
来计算字符串的字节长度,放在字符串前面中文是占用两个字节
> len = "123456"
> print(#len)
6
> print(#"123456")
6
> print(#"你好")
4
table
表
最简单构造表达式是{},用来创建一个空表
也可以在表里添加一些数据,直接初始化表
默认索引从
1
开始不会固定长度大小
索引不可以是数字和字符串,只能是普通遍历
-- 空表
local tbl1 = {}
-- 直接初始化表
local tabl2 = {"apple", "pear", "orange", "grape"}
-- 两种引用方式
local tabl3 = {a="aa"}
pirnt(tabl3["a"])
pirnt(tabl3.a)
表的遍历
local tabl2 = {"apple", "pear", "orange", "grape"}
for key, val in pairs(tabl2) do
print("key: ", key," val: ", val)
end
#
获取表长度,只能获取常规数组的大小如果数组有一个“空洞” (就是说,
nil
值被夹在非空值之间), 那么#t
可能是指向任何一个是nil
值的前一个位置的下标 (就是说,任何一个nil
值都有可能被当成数组的结束),测试发现,只有同时存在两个nil
,才会变成取第一个nil
之前的长度
ab4 = {}
tab4[1] = "1"
tab4[2] = nil
tab4[3] = "2"
tab4[4] = nil
print("tab4的长度", #tab4)
--tab4的长度 1
tab5 = {}
tab5[1] = "1"
tab5[2] = nil
tab5[3] = "2"
tab5[4] = "4"
print("tab5的长度", #tab5)
--tab5的长度 4
tab6 = {1, nil, 3}
print("tab6的长度", #tab6)
--tab6的长度 3
tab6 = {1, nil, 3, nil}
print("tab6的长度", #tab6)
--tab6的长度 1
userdata
自定义类型
是一种用户自定义数据。用于表示一种由应用程序或
C/C++
语言库所创建的类型,可以将任意C/C++
的任意数据类型的数据(通常是struct
和 指针)存储到Lua
变量中调用。
变量
变量在使用前,需要在代码中进行声明,即创建该变量。
Lua 变量三种类型,访问局部变量的速度比全局变量更快。
- 全局变量
- 局部变量
- 表中的域
Lua 中的变量全是全局变量,哪怕是语句块或是函数里,除非用 local 显式声明为局部变量。局部变量的作用域为从声明位置开始到所在语句块结束。
a = 5 -- 全局变量
local b = 5 -- 局部变量
function joke()
c = 5 -- 全局变量
local d = 6 -- 局部变量
end
joke()
print(c,d) --> 5 nil
do
local a = 6 -- 局部变量
b = 6 -- 对局部变量重新赋值
print(a,b); --> 6 6
end
print(a,b) --> 5 6
赋值
改变一个变量的值
可以对多个变量同时赋值,变量列表和值列表的各个元素用逗号分开,赋值语句右边的值会一次赋值给左边
a, b = 10, 11 <--> a=10; b=11
遇到赋值语句Lua会先计算右边所有的值然后再执行赋值操作,所以我们可以这样进行交换变量的值:
x, y = 1, 2
print(x, y) -- 1 2
x, y = y, x
print(x, y) -- 2 1
当变量个数和值的个数不一致时,Lua会一直以变量个数为基础采取以下策略:
- 变量个数 > 值的个数 按变量个数补足nil
- 变量个数 < 值的个数 多余的值会被忽略
a, b, c = 0, 1
print(a,b,c) --> 0 1 nil
a, b = 1, 2, 3
print(a,b) --> 1 2
a, b, c = 0
print(a,b,c) --> 0 nil nil
运算符
Lua提供了以下几种运算符类型:
- 算术运算符
- 关系运算符
- 逻辑运算符
- 其他运算符
算术运算符
操作符 | 描述 | 实例 |
---|---|---|
+ | 加法 | 1+2=3 |
- | 减法 | 2-1=1 |
* | 乘法 | 2*3=6 |
/ | 除法 | 3/2=1.5 |
% | 取余 | 5%2=1 |
^ | 乘幂 | 2^3=8 |
- | 负号 | -2 |
// | 取整(>=lua5.3) | 5//2=2 |
关系运算符
操作符 | 描述 | 实例 |
---|---|---|
== | 等于 | 10 == 20:false |
~= | 不等于 | 10 ~= 20:true |
> | 大于 | 10 > 20:false |
< | 小于 | 10 < 20:true |
>= | 大于等于 | 10 >= 20:false |
<= | 小于等于 | 10 <= 20:true |
逻辑运算符
操作符 | 描述 | 实例 |
---|---|---|
and | 逻辑与操作符 | false and true =>> false |
or | 逻辑或操作符 | false or true =>> true |
not | 逻辑非操作符 | not false =>> true |
循环
循环类型 | 描述 |
---|---|
while 循环 | 在条件为 true 时,让程序重复地执行某些语句。执行语句前会先检查条件是否为 true 。 |
for 循环 | 重复执行指定语句,重复次数可在 for 语句中控制。 |
repeat...until | 重复执行循环,直到 指定的条件为真时为止 |
循环嵌套 | 可以在循环内嵌套一个或多个循环语句(while do ... end ;for ... do ... end ;repeat ... until ;) |
while
循环
while 循环语句在判断条件为 true 时会重复执行循环体语句。
a=10
while( a < 20 )
do
print("a 的值为:", a)
a = a+1
end
for
循环
for 循环语句可以重复执行指定语句,重复次数可在 for 语句中控制。
for 语句有两大类:
- 数值for循环
- exp1 变量
- exp2 条件判断
- exp3 步长,默认1,自增时可省略
for var=exp1, exp2[, exp3] do
<执行体>
end
实例:
-- 每次增加1
for i=1, 3 do
print(i)
end
-- 1 2 3
-- 每次减少1
for i=3,1,-1 do
print(i)
end
-- 3 2 1
for 循环中,循环的索引 i 为外部索引,修改循环语句中的内部索引 i,不会影响循环次数,了解即可,不建议这么写
for i=1,10 do
i = 10
print("one time,i:"..i)
end
--
one time,i:10
one time,i:10
one time,i:10
one time,i:10
one time,i:10
one time,i:10
one time,i:10
one time,i:10
one time,i:10
one time,i:10
--
- 泛型for循环
pairs
遍历表中全部key,valueipairs
从下标为1开始遍历,然后下标累加1,如果某个下标元素不存在就终止遍历,ipairs
在迭代过程中如果遇到nil
时会直接停止
--打印数组a的所有值
a = {"one", "two", "three"}
for i, v in ipairs(a) do
print(i, v)
end
-- 非数字下标不遍历
tab = {1,2,a= nil,"d",b="bb"}
for i,v in ipairs(tab) do
print(i,v)
end
--[=[结果
1 1
2 2
3 d
]=]
-- ipairs在迭代过程中如果遇到 nil 时会直接停止。
tab = {1,2,a= nil,nil,"d"}
for i,v in ipairs(tab) do
print(i,v)
end
--[=[结果
1 1
2 2
]=]
repeat...until
直到型循环
会先做一次循环,再进行判断,如果条件满足则退出循环,否则继续循环。就像找东西,找到了即结束
--[ 变量定义 --]
a = 1
--[ 执行循环 --]
repeat
print("a的值为:", a)
a = a + 1
until( a > 5 )
循环控制语句
控制语句 | 描述 |
---|---|
break 语句 | 退出当前循环或语句,并开始脚本执行紧接着的语句。 |
goto 语句 | 将程序的控制点转移到一个标签处,这个对逻辑有破坏性,非必要,不要使用 |
break
break 语句插入在循环体中,用于退出当前循环或语句,并开始脚本执行紧接着的语句。
如果你使用循环嵌套,break语句将停止最内层循环的执行,并开始执行的外层的循环语句。
--[ 定义变量 --]
a = 1
--[ while 循环 --]
while( a < 10 )
do
print("a 的值为:", a)
a=a+1
if( a > 2)
then
--[ 使用 break 语句终止循环 --]
break
end
end
--[=[结果
1
2
]=]
goto
语句
lua 5.2 新增的
goto 语句允许将控制流程无条件地转到被标记的语句处。
语法格式如下所示:
-- 跳转到标记
goto Label
-- 标记 Label 的格式
:: Label ::
实例
local a = 1
::label:: print("--- goto label ---")
a = a+1
if a < 3 then
goto label -- a 小于 3 的时候跳转到标签 label
end
--[=[结果,输出了两遍
--- goto label ---
--- goto label ---
]=]
流程控制
if
语句
a = 10;
if( a < 20 )
then
print("a 小于 20" );
end
print("a 的值为:", a);
if...else
语句
a = 100;
if( a < 20 )
then
print("a 小于 20" )
else
print("a 大于 20" )
end
print("a 的值为 :", a)
if...elseif...else
语句
a = 100
if( a == 10 )
then
print("a 的值为 10" )
elseif( a == 20 )
then
print("a 的值为 20" )
elseif( a == 30 )
then
print("a 的值为 30" )
else
print("没有匹配 a 的值" )
end
print("a 的真实值为: ", a )
函数
在Lua中,函数是对语句和表达式进行抽象的主要方法。既可以用来处理一些特殊的工作,也可以用来计算一些值。
--[[ 函数返回两个值的最大值 --]]
function max(num1, num2)
if (num1 > num2) then
result = num1;
else
result = num2;
end
return result;
end
-- 调用函数
print("两值比较最大值为 ",max(10,4))
print("两值比较最大值为 ",max(5,6))
可变参数
function add(...)
local s = 0
for i, v in ipairs{...} do --> {...} 表示一个由所有变长参数构成的数组
s = s + v
end
return s
end
print(add(3,4,5,6,7)) --->25
模块和包
模块类似于一个封装库,从 Lua 5.1 开始,Lua 加入了标准的模块管理机制,可以把一些公用的代码放在一个文件里,以 API 接口的形式在其他地方调用,有利于代码的重用和降低代码耦合度。
Lua 的模块是由变量、函数等已知元素组成的 table,因此创建一个模块很简单,就是创建一个 table,然后把需要导出的常量、函数放入其中,最后返回这个 table 就行。
模块:
-- 文件名为 module.lua
-- 定义一个名为 module 的模块
module = {
func4 = function ()
print("这是一个公有有函数!")
end
}
-- 定义一个常量
module.constant = "这是一个常量"
-- 定义一个函数
function module.func1()
print("这是一个公有函数!")
end
local function func2()
print("这是一个私有函数!")
end
function module.func3()
func2()
end
return module
require
函数
Lua提供了一个名为require的函数用来加载模块。
两种方式
- require(“<模块名>”)
- require “<模块名>”
直接使用模块
require("module")
print(module.constant)
module.func3()
给加载的模块定义一个别名变量
local m = require("module")
print(m.constant)
m.func3()