跳到主要内容

基础语法

示例

下方示例中,两个减号(--)后面的内容为单行注释。

示例1主要说明局部变量和脚本级变量作用域的区别。

function func()     -- 定义函数,运行时打印a,b
local a = 1 -- 局部变量
b = 2 -- 脚本级变量
print(a)
print(b)
end

func() -- 执行函数,打印a和b的值分别为1和2
print(a) --> nil(在变量作用域外调用,打印为nil,下同)
print(b) --> 2

示例2主要说明局部变量可以和脚本级变量同名,但仅在函数内生效。do/end等流程控制(循环、条件判断)的代码块也属于函数。

a = "a"

for i=10,1,-1 do
do
local a = 6 -- 局部变量
print(a) --> 6,语句块内调用的为局部变量a
end

print(a) --> a,语句块外调用的为脚本级变量a

示例3主要说明全局变量和另两种变量作用域的区别,以及全局变量的全局保持功能。

-- 工程1的src0.lua文件
-- 假设已在全局变量页面添加了两个全局变量g1和g2
-- g1非全局保持,取值为10
-- g2全局保持,取值为20

local a = 1
b = 2
print(a) --> 1
print(b) --> 2

print(g1) --> 10
print(g2) --> 20
SetGlobalVariable("g1",11) -- 对非全局保持的全局变量赋值
SetGlobalVariable("g2",22) -- 对全局保持的全局变量赋值
print(g1) --> 11
print(g2) --> 22

-- 工程2的src0.lua文件
-- 工程2在工程1之后运行

print(a) --> nil
print(b) --> nil
print(g1) --> 10(非全局保持的变量恢复成了工程1修改前的值)
print(g2) --> 22(全局保持的变量变成了工程1修改后的值)

变量名称可以是任意非数字打头的字母、下划线和数字组成的字符串,Lua保留的关键字除外。

Lua 变量不需要类型定义,只需要为变量赋值,Lua会根据值自动判断变量的类型。在脚本中对已赋值的变量赋予不同类型的值会改变变量的类型;但在监控 > 全局变量页面设置的变量不可改变类型,赋值的类型必须和创建变量时选择的类型一致,否则控制器运行脚本时会报错。

Lua支持多种数据类型,较为常见的包括数字(number),布尔值(boolean),字符串(string)和表(table)。Lua中的数组是table的一种。

Lua中还有一种特殊的数据类型为nil,nil 表示空(没有任何有效值),例如打印一个没有赋值的变量,便会输出一个 nil 值。

数字

Lua中的number为双精度类型的实浮点数,支持各种运算,以下写法均被视为number:

  • 2
  • 2.2
  • 0.2
  • 2e+1
  • 0.2e-1
  • 7.8263692594256e-06

布尔值

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

字符串

string是由数字、字母、下划线组成的一串字符。string可以使用以下三种方式来表示:

  • 单引号间的一串字符。
  • 双引号间的一串字符。
  • [[ 与 ]] 间的一串字符。 在对一个数字字符串上进行算术操作时,Lua 会尝试将这个数字字符串转成一个数字。

Lua 提供了很多的方法来支持字符串的操作:

方法说明
string.upper (argument)字符串全部转为大写字母
string.lower (argument)字符串全部转为小写字母
string.gsub(mainString, findString,replaceString,num)在字符串中替换。
string.find (str, substr, [init, [end]])在一个指定的目标字符串 str 中搜索指定的内容 substr,如果找到了一个匹配的子串,就会返回这个子串的起始索引和结束索引,不存在则返回 nil。
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)string.match()只寻找源字串str中的第一个配对. 参数init可选, 指定搜寻过程的起点, 默认为1。 在成功配对时, 函数将返回配对表达式中的所有捕获结果; 如果没有设置捕获标记, 则返回整个配对字符串. 当没有成功的配对时, 返回nil
string.sub(s, i [, j])用于截取字符串。s为要截取的字符串,i为截取开始位置,j为截取结束位置,默认为-1,最后一个字符。
示例:
str = "Lua"
print(string.upper(str)) --字符串全部转为大写字母,打印结果:LUA
print(string.lower(str)) --字符串全部转为小写字母,打印结果:lua
print(string.reverse(str)) --字符串反转,打印结果:aul
print(string.len("abc")) --计算字符串abc的长度,打印结果:3
print(string.format("the value is: %d",4)) --打印结果:the value is:4
print(string.rep(str,2)) --字符串复制2次,打印结果:LuaLua
string1 = "cn."
string2 = "dobot"
string3 = ".cc"
print("连接字符串",string1..string2..string3) -- 使用..进行字符串连接,打印结果:cn.dobot.cc

string1 = [[aaaa]]
print(string.gsub(string1,"a","z",3)) --在字符串中替换,打印结果:zzza

print(string.find("Hello Lua user", "Lua", 1)) --在字符串中搜索Lua,返回子串的起始索引和结束索引,打印结果:7,9

sourcestr = "prefix--runoobgoogletaobao--suffix"
sub = string.sub(sourcestr, 1, 8) --取字符串前缀,第1个到第8个
print("\n截取", string.format("%q", sub)) --打印结果:截取 "prefix--"

table是一组带索引的数据。

最简单的构造函数是,用来创建一个空表。可以直接初始化表。

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

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

通过#符号可以获取表的长度。

tbl = {[1] = 2, [2] = 6, [3] = 34, [4] =5}
print("tbl 长度 ", #tbl) -- 打印结果为4

Lua 提供了很多的方法来支持表的操作:

方法说明
table.concat (table [, sep [, start [, end]]])concat是concatenate(连锁, 连接)的缩写. table.concat()函数列出参数中指定table的数组部分从start位置到end位置的所有元素, 元素间以指定的分隔符(sep)隔开
table.insert (table, [pos,] value)在table的数组部分指定位置(pos)插入值为value的一个元素. pos参数可选, 默认为表的末尾
table.remove (table [, pos])返回table数组部分位于pos位置的元素. 其后的元素会被前移. pos参数可选, 默认为table长度, 即从最后一个元素删起
table.sort (table [, comp])对给定的table进行升序排序

示例1:

fruits = {}        -- 初始化表
fruits = {"banana","orange","apple"} -- 为表赋值

print("连接后的字符串 ",table.concat(fruits,", ", 2,3)) -- 指定索引来连接table,连接后的字符串 orange, apple

-- 在末尾插入
table.insert(fruits,"mango")
print("索引为 4 的元素为 ",fruits[4]) --打印结果:索引为4的元素为 mango

-- 在索引为 2 的键处插入
table.insert(fruits,2,"grapes")
print("索引为 2 的元素为 ",fruits[2]) --打印结果:索引为2的元素为 grapes

print("最后一个元素为 ",fruits[5]) --打印结果:最后一个元素为 mango
table.remove(fruits)
print("移除后最后一个元素为 ",fruits[5]) --打印结果:移除后最后一个元素为 nil

示例2:

fruits = {"banana","orange","apple","grapes"}
print("排序前")
for k,v in ipairs(fruits) do
print(v) --打印结果:banana orange apple grapes
end
--进行升序排序
table.sort(fruits)
print("排序后")
for k,v in ipairs(fruits) do
print(v) --打印结果:apple banana grapes orange
end

数组

数组,就是相同数据类型的元素按一定顺序排列的集合,可以是一维数组和多维数组。Lua 数组的索引键值可以使用整数表示,数组的大小不是固定的。

一维数组:最简单的数组,其逻辑结构是线性表。 多维数组:即数组中包含数组或一维数组的索引键对应一个数组。

示例1:一维数组可以用for循环出数组中的元素。使用整数索引来访问数组元素,如果索引没有值则返回nil。

array = {"Lua", "Tutorial"}  --创建一维数组     
for i= 0, 2 do
print(array[i]) --打印结果分别为:nil Lua Tutorial
end
在 Lua 索引值是以 1 为起始,但也可以指定 0 开始。除此外还可以以负数为数组索引值。

array = {}
for i= -2, 2 do
array[i] = i*2+1 --为一维数组赋值
end
for i = -2,2 do
print(array[i]) --打印结果分别为:-3 -1 1 3 5
end

示例2:一个三行三列的阵列多维数组

-- 初始化数组
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]) --打印结果分别为:1 2 3 2 4 6 3 6 9
end
end