逻辑运算符认为 false 和 nil 是假(false),其他为真,0 也是 true.
and 和 or ,~=
and 和 or 的运算结果不是 true 和 false,而是和它的两个操作数相关。
~=表示不等于
a and b -- //如果 a 为 false,则返回 a,否则返回 b
a or b -- //如果 a 为 true,则返回 a,否则返回 b
一个很实用的技巧:如果 x 为 false 或者 nil 则给 x 赋初始值 v
x = x or v
and 的优先级比 or 高
and前为假,返回第一个
or前为真,返回第一个
a ? b : c <==>(a and b) or c
print(not nil) --> true
print(not false) --> true
print(not 0) --> false
print(not not nil) --> false
模式匹配
.(点): 与任何字符配对
%a: 与任何字母配对
%c: 与任何控制符配对(例如\n)
%d: 与任何数字配对
%l: 与任何小写字母配对
%p: 与任何标点(punctuation)配对
%s: 与空白字符配对
%u: 与任何大写字母配对
%w: 与任何字母/数字配对
%x: 与任何十六进制数配对
%z: 与任何代表0的字符配对
%x(此处x是非字母非数字字符): 与字符x配对. 主要用来处理表达式中有功能的字符(^$()%.[]*+-?)的配对问题, 例如%%与%配对
[数个字符类]: 与任何[]中包含的字符类配对. 例如[%w_]与任何字母/数字, 或下划线符号(_)配对
[^数个字符类]: 与任何不包含在[]中的字符类配对. 例如[^%s]与任何非空白字符配对
当上述的字符类用大写书写时, 表示与非此字符类的任何字符配对. 例如, %S表示与任何非空白字符配对.例如,'%A'非字母的字符:
…操作
print("Hello " .. "World") --> Hello World --连接
print(0 .. 1) --> 01
优先级
^
not - (unary)
* /
+ -
..
< > <= >= ~= ==
and
or
除了^和…外
所有的二元运算符都是左连接的。
a+i < b/2+1 <--> (a+i) < ((b/2)+1)
5+x^2*8 <--> 5+((x^2)*8)
a < y and y <= z <--> (a < y) and (y <= z)
-x^2 <--> -(x^2)
x^y^z <--> x^(y^z)
赋值
Lua 可以对多个变量同时赋值,变量列表和值列表的各个元素用逗号分开,赋值语 句右边的值会依次赋给左边的变量
a, b = 10, 2*x <==> a=10; b=2*x
//变量个数 > 值的个数 按变量个数补足 nil
//变量个数 < 值的个数 多余的值会被忽略
a, b, c = 0,1
print(a,b,c) //0 1 nil
a, b = a+1, b+1, b+2 // value of b+2 is ignored
print(a,b) // 1 2
a, b, c = 0
print(a,b,c) //0 nil nil
x, y = y, x //swap 'x' for 'y'
a[i], a[j] = a[j], a[i] //swap'a[i]' for 'a[i]'
局部变量
--与全局变量不同,局部变量只在被声明的那个代码块内有效
x = 10
local i = 1 -- local to the chunk
while i<=x do
local x = i*2 -- local to the while body
print(x) -- 2, 4, 6, 8, ...
i = i + 1
end
if i > 20 then
local x -- local to the "then" body
x = 20
print(x + 2)
else
print(x) -- 10 (the global one)
end
print(x) -- 10 (the global one)
while condition do
statements;
end;
repeat
statements;
until conditions;
多行注释:
–[[ --]]
在构造函数中域分隔符逗号(“,”)可以用分号(“;”)替代
通常我们使用分号用来分割不同类型的表元素。
{x=10, y=45; "one", "two", "three"}
循环控制语句
if conditions then
then-part
elseif conditions then
elseif-part
.. --->多个 elseif
else
else-part
end;
while condition do
statements;
end;
repeat
statements;
until conditions;
泛型for循环:
泛型 for 循环通过一个迭代器函数来遍历所有值
a = {"one", "two", "three"}
for i, v in ipairs(a) do
print(i, v)
end
i是数组索引值
v是对应索引的数组元素值
ipairs是一个迭代器函数,用来迭代数组。
1 one
2 two
3 three
总结:
1:for语句分为两类,数值for循环,泛型for循环
2:数值for循环中的表达式在循环开始前进行一次性求值,之后不再进行求值
3:泛型for循环通过一个迭代器函数来遍历所有值
Lua 函数中,在 return 后列出要返回的值得列表即可返回多值,如:
function maximum (a)
local mi = 1 -- maximum index
local m = a[mi] -- maximum value
for i,val in ipairs(a) do
if val > m then
mi = i
m = val
end
end
return m, mi end
print(maximum({8,10,23,12,5})) --> 23 3
unpack 返回 a 所有的元素作为 f()的参数
table
创建
可以使用花括号{}来创建一个新的table,并在其中添加键值对。例如:
local myTable = {key1 = "value1", key2 = "value2", key3 = "value3"}
这将创建一个名为myTable的table,并向其中添加三个键值对。
访问
t[i]
t.i
两者等价
可以使用table[key]的语法来访问table中的值。如果指定的键存在,则返回其对应的值;否则返回nil。例如:
print(myTable["key1"]) -- 输出"value1"
也可以使用点号.的语法来访问table中的值,这种方法更加简洁。例如:
print(myTable.key2) -- 输出"value2"
需要注意的是,当使用字符串作为索引时,一定要用引号将字符串括起来。否则,Lua会把它误认为是一个变量名。
添加删除修改
可以通过赋值语句来添加、删除和修改table中的值。例如:
--添加一个键值对
myTable.newKey = "newValue"
-- 删除一个键值对
myTable.key3 = nil
-- 修改一个键对应的值
myTable.key1 = "new value1"
遍历
可以使用pairs()函数来遍历table中的所有键值对。该函数返回两个值:当前键和对应的值。例如:
for key, value in pairs(myTable) do
print(key, value)
end
也可以使用ipairs()函数来遍历table中的所有数字键。该函数返回两个值:当前索引和对应的值。例如:
local myArray = {"value1", "value2", "value3"}
for index, value in ipairs(myArray) do
print(index, value)
end
table.maxn()
返回最大索引值
tab={"I","asd","we","as","awqe"}
print(table.maxn(tab))--5
table.remove()
移除数据,默认移除最后一个
tab={"I","asd","we","as","awqe"}
table.remove(tab)--默认移除最后一个
for k,v in pairs(tab) do
io.write(v.." ")--I asd we as
end
table.remove(tab,2)
for k,v in pairs(tab) do
io.write(v.." ")--I we as
end
table.sort()
排序
tab={12,3,2,4,6,44}
table.sort(tab)
for k,v in pairs(tab) do
io.write(v.." ")--2 3 4 6 12 44
end
深拷贝
可以使用table库中的函数==table.clone()或table.deepcopy()==来深拷贝一个table。深拷贝会创建一个与原始table相同的新table,但是其实际上是完全独立的,对新table的修改不会影响原始table。例如:
local newTable = table.deepcopy(myTable)
local arr={name="wang",age=24,gender="male"}
print(arr[name]) --nil
print(arr.age) --24
print(arr["name"])--wang
print(arr["age"])--24
arr["1"]=333
print(arr["1"])--333
print(arr.name)--wang
string
在lua中 ’ ’ 和 " " 是等价的 需要注意的是字符串中的第一个字符索引为1
获取字符串长度
Lua 中的 #
运算符只能计算一个 table 中连续的、非空元素的个数,并且当遇到第一个空元素或 nil 值时就会停止计算。因此,如果一个 table 包含了不连续的元素或者 nil 值,使用 #
运算符可能会得到错误的结果。
1.#str
2.string.len(str)
a="hello"
print(#a)--5
print(string.len(a))--5
字符串的连接
…
a="hello"
a.." world" --hello world
print(a)--hello
有字符串参与的算术运算都会被当成浮点运算处理
print("5"+1) --6
string.rep(s,n)
返回字符串s重复n次的结果
a="hello"
print(string.rep(a,3)) --hellohellohello
string.reverse(s,n)
获取字符串的翻转
print(string.reverse("hello"))--olleh
string.lower(s)
将字符串中的大写字母都转换成小写函数
string.upper(s)
将字符串中的小写字母都转换成大写函数
string.sub(s,i,j)
从字符串s中提取第i个到第j个字符(包括第i个和第j个字符)
string.format()
对字符串格式化和将数值输出为字符串
a=10
b=11
str1="Hello"
str2="world"
print(string.format("a=%d b=%d",a,b)) --a=10 b=11
print(string.format("%s%s",str1,str2)) --Helloworld
string.find(s,t)
在s中查找t字符串 如果找到返回索引否则返回nil
str1="Hello"
print(string.find(str1,"ell"))--2 4
print(string.find(str1,'l')) --3 3 只能查找一个
print(string.find(str1,'aw')) --nil
string.gsub(s,t,w)
将s中的所有t字符串替换为w 返回替换后的字符串和替换次数
str1="Hello"
print(string.gsub(str1,'l','w'))--Hewwo 2
print(string.gsub(str1,'i','n'))--Hello 0
string.match(s,t)
返回匹配的字符串t
print(string.match("hello world","hw"))--nil
print(string.match("hello world","hello"))--hello
io.write
io.write
和io.read
是Lua IO库中的两个重要的函数,它们分别用于写入和读取数据。
io.write
函数:
该函数用于将一系列的值写入当前输出文件。它的语法如下:
io.write(v1, v2, ...)
其中v1、v2等为待写入的值,可以是字符串、数字或其他类型的Lua值。多个值之间可以使用逗号分隔。该函数会自动将这些值转换为字符串并写入当前输出文件。
例如,下面的代码向标准输出流(控制台)打印了一个字符串和一个数字:
io.write("Hello, ", 123, "\n")
运行结果为:Hello, 123
io.read
函数:
该函数用于从当前输入文件中读取一定数量的字符或字节,并返回读取到的字符串。它的语法如下:
io.read([format])
可选的format参数指定读取的格式,默认为"*l"(按行读取)。常见的格式有:
- “*n”: 读取一个数字。
- “*a”: 读取整个文件。
- “*l”: 读取一行文本。
- “n”: 读取固定长度的字节数。
例如,下面的代码从标准输入流(控制台)读取一行文本并打印出来:
local line = io.read("*l")
print(line)
运行结果为:输入的文本被打印出来。
math库常用函数
math.abs(x)
获取绝对值
math.ceil(x)
获取大于或等于x的最小整数
print(math.ceil(2.1))--3
math.floor(x)
获取小于或等于x的最大整数
print(math.floor(2.1)) --2
math.cos(x)
获取余弦值 其中x传入为弧度
print(math.cos(1.0/3*math.pi)) --0.5
math.deg(x)
将x 从弧度转化为角度
print(math.deg(1.0/6*math.pi))--30
math.rad(x) 从角度转化为弧度
math.modf(x)
返回x的整数部分和小数部分 第二个结果总是浮点数
print(math.modf(10.0)) --10 0
print(math.modf(10.1)) --10 0.1
math.pi 圆周率
随机数
math.random([m[,n]])
print(math.random())--返回一个[0,1]之间的浮点数
print(math.random(2,4))--返回一个[2,4]之间的整数
print(math.random(10))--返回1-10之间的整数
math.tointeger(x)
转化为整数 如果可以转化返回整数否则返回nil
math.tointeger(10.1)-- nil
math.tointeger(10)--10
math.tointeger('')--nil
math.type(x)
判断float 或int类型
math.type(10.1)--float
math.type(10)--integer
math.type('')--nil
select("#",...) 获取可变参数的数量:
实例
function average(...)
result = 0
local arg={...}
for i,v in ipairs(arg) do
result = result + v
end
print("总共传入 " .. select("#",...) .. " 个数")
return result/select("#",...)
end
print("平均值为",average(10,5,3,4,5,6))
以上代码执行结果为:
总共传入 6 个数
平均值为 5.5