文章目录
简记
lua
下标从1开始- 迭代器pairs/ipairs
- 函数是一等公民
变量
-
lua中变量是对值的引用
-
默认全局变量
-
局部变量添加关键字local
数据类型
nil | 用于将值与有一些数据或没有(无)数据区分开来。 |
---|---|
boolean | 包括 true 和 false 作为值。 一般用于条件检查。 |
number | 表示实数(双精度浮点数)。 |
string | 表示字符数组。 |
function | 表示用 C 或 Lua 编写的方法。 |
userdata | 表示任意 C 数据。 |
thread | 代表独立的执行线程,用于实现协程。 |
table | 表示普通数组、符号表、集合、记录、图形、树等,实现关联数组。 它可以保存任何值(nil 除外)。 |
运算符
算术运算符
下表显示了 Lua 语言支持的所有算术运算符。 假设变量 A 持有 10 并且变量 B 持有 20 然后
运算符 | 描述 | 示例 |
---|---|---|
+ | 添加两个操作数 | A + B 将得到 30 |
- | 从第一个操作数中减去第二个操作数 | A - B 将得到 -10 |
* | 两个操作数相乘 | A * B 将得到 200 |
/ | 分子除以分母 | B / A 将得到 2 |
% | 取模运算符和整数除法后的余数 | B % A 将得到 0 |
^ | 指数运算符取指数 | A^2 将得到 100 |
- | 一元 - 运算符作为否定 | -A 将得到 -10 |
关系运算符
下表显示了 Lua 语言支持的所有关系运算符。 假设变量 A 持有 10 并且变量 B 持有 20 然后
运算符 | 描述 | 示例 |
---|---|---|
== | 检查两个操作数的值是否相等,如果是则条件为真。 | (A == B) is not true. |
~= | 检查两个操作数的值是否相等,如果值不相等则条件为真。 | (A ~= B) is true. |
> | 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 | (A > B) is not true. |
< | 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 | (A < B) is true. |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 | (A >= B) is not true. |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是的,则条件将变为true。 | (A <= B) is true. |
逻辑运算符
下表显示了 Lua 语言支持的所有逻辑运算符。 假设变量 A 为真,变量 B 为假,则 −
运算符 | 描述 | 示例 |
---|---|---|
and | 称为逻辑与运算符。 如果两个操作数都不为零,则条件为真。 | (A and B) is false. |
or | 称为逻辑或运算符。 如果两个操作数中的任何一个非零,则条件变为真。 | (A or B) is true. |
not | 称为逻辑非运算符。用于逆转其操作数的逻辑状态。 如果条件是 true,则逻辑非运算符结果会是 false。 | !(A and B) is true. |
杂项运算符
Lua 语言支持的其他运算符包括 concatenation 和 length。
运算符 | 描述 | 示例 |
---|---|---|
... | 连接两个字符串。 | a...b 其中 a 是"Hello",b 是"World",将返回"Hello World"。 |
# | 返回字符串或表格长度的一元运算符。 | #"Hello" 将返回 5 |
列表(表)
表是lua中唯一的数据结构
可以用数字或者字符串做key
lua
--样本表初始化
mytable = {}
表格操作
有用于表格操作的内置函数,它们列在下表中。
序号 | 方法 & 用途 |
---|---|
1 | **table.concat (table [, sep [, i [, j]]])**根据给定的参数连接表中的字符串。 有关详细信息,请参见示例。 |
2 | **table.insert (table, [pos,] value)**在表中的指定位置插入一个值。 |
3 | **table.maxn (table)**返回最大的数字索引。 |
4 | **table.remove (table [, pos])**从表中删除值。 |
5 | **table.sort (table [, comp])**根据可选的比较器参数对表进行排序。 |
让我们看一下上述函数的一些示例。
表连接
我们可以使用 concat 函数来连接两个表,如下所示 −
lua
fruits = {"banana","orange","apple"}
-- returns concatenated string of table
print("Concatenated string ",table.concat(fruits))
--concatenate with a character
print("Concatenated string ",table.concat(fruits,", "))
--concatenate fruits based on index
print("Concatenated string ",table.concat(fruits,", ", 2,3))
当我们运行上述程序时,我们将得到以下输出 −
lua
Concatenated string bananaorangeapple
Concatenated string banana, orange, apple
Concatenated string orange, apple
插入和删除
在表格中插入和删除项目是最常见的表格操作。 下面解释一下。
lua
fruits = {"banana","orange","apple"}
-- insert a fruit at the end
table.insert(fruits,"mango")
print("Fruit at index 4 is ",fruits[4])
--insert fruit at index 2
table.insert(fruits,2,"grapes")
print("Fruit at index 2 is ",fruits[2])
print("The maximum elements in table is",table.maxn(fruits))
print("The last element is",fruits[5])
table.remove(fruits)
print("The previous last element is",fruits[5])
当我们运行上述程序时,我们将得到以下输出。−
Fruit at index 4 is mango
Fruit at index 2 is grapes
The maximum elements in table is 5
The last element is mango
The previous last element is nil
排序表
我们经常需要按特定顺序对表格进行排序。 排序函数按字母顺序对表中的元素进行排序。 下面显示了一个示例。
lua
fruits = {"banana","orange","apple","grapes"}
for k,v in ipairs(fruits) do
print(k,v)
end
table.sort(fruits)
print("sorted table")
for k,v in ipairs(fruits) do
print(k,v)
end
当我们运行上述程序时,我们将得到以下输出 −
1 banana
2 orange
3 apple
4 grapes
sorted table
1 apple
2 banana
3 grapes
4 orange
模块
lua
require "<模块名>"
元表
- setmetatable(table,metatable): 对指定 table 设置元表(metatable),如果元表(metatable)中存在 __metatable 键值,setmetatable 会失败。
- getmetatable(table): 返回对象的元表(metatable)。
以下实例演示了如何对指定的表设置元表:
lua
mytable = {} *-- 普通表*
mymetatable = {} *-- 元表*
setmetatable(mytable,mymetatable) *-- 把 mymetatable 设为 mytable 的元表*
以上代码也可以直接写成一行:
lua
mytable = setmetatable({},{})
以下为返回对象元表:
lua
getmetatable(mytable) -- 这会返回 mymetatable
__index 元方法
这是 metatable 最常用的键。
当你通过键来访问 table 的时候,如果这个键没有值,那么Lua就会寻找该table的metatable(假定有metatable)中的__index 键。如果__index包含一个表格,Lua会在表格中查找相应的键。
如果__index包含一个函数的话,Lua就会调用那个函数,table和键会作为参数传递给函数。
__index 元方法查看表中元素是否存在,如果不存在,返回结果为 nil;如果存在则由 __index 返回结果。
实例
lua
mytable = setmetatable({key1 = "value1"}, {
__index = function(mytable, key)
if key == "key2" then
return "metatablevalue"
else
return nil
end
end
})
print(mytable.key1,mytable.key2)
实例输出结果为:
value1 metatablevalue
实例解析:
-
mytable 表赋值为 {key1 = "value1"}。
-
mytable 设置了元表,元方法为 __index。
-
在mytable表中查找 key1,如果找到,返回该元素,找不到则继续。
-
在mytable表中查找 key2,如果找到,返回 metatablevalue,找不到则继续。
-
判断元表有没有__index方法,如果__index方法是一个函数,则调用该函数。
-
元方法中查看是否传入 "key2" 键的参数(mytable.key2已设置),如果传入 "key2" 参数返回 "metatablevalue",否则返回 mytable 对应的键值。
我们可以将以上代码简单写成:
lua
mytable = setmetatable({key1 = "value1"}, { __index = { key2 = "metatablevalue" } })
print(mytable.key1,mytable.key2)
总结
Lua 查找一个表元素时的规则,其实就是如下 3 个步骤:
- 1.在表中查找,如果找到,返回该元素,找不到则继续
- 2.判断该表是否有元表,如果没有元表,返回 nil,有元表则继续。
- 3.判断元表有没有 __index 方法,如果 __index 方法为 nil,则返回 nil;如果 __index 方法是一个表,则重复 1、2、3;如果 __index 方法是一个函数,则返回该函数的返回值。
__newindex 元方法
__newindex 元方法用来对表更新,__index则用来对表访问 。
当你给表的一个缺少的索引赋值,解释器就会查找__newindex 元方法:如果存在则调用这个函数而不进行赋值操作。
实例
lua
mymetatable = {}
mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })
print(mytable.key1)
mytable.newkey = "新值2"
print(mytable.newkey,mymetatable.newkey)
mytable.key1 = "新值1"
print(mytable.key1,mymetatable.key1)
以上实例执行输出结果为:
value1
nil 新值2
新值1 nil
以上实例中表设置了元方法 __newindex,在对新索引键(newkey)赋值时(mytable.newkey = "新值2"),会调用元方法,而不进行赋值。而如果对已存在的索引键(key1),则会进行赋值,而不调用元方法 __newindex。
以下实例使用了 rawset 函数来更新表:
实例
lua
mytable = setmetatable({key1 = "value1"}, {
__newindex = **function**(mytable, key, value)
rawset(mytable, key, "**\"**"..value.."**\"**")
**end**
})
mytable.key1 = "new value"
mytable.key2 = 4
print(mytable.key1,mytable.key2)
以上实例执行输出结果为:
new value "4"
为表添加操作符
以下实例演示了两表相加操作:
实例
lua
-- 计算表中最大值,table.maxn在Lua5.2以上版本中已无法使用
-- 自定义计算表中最大键值函数 table_maxn,即返回表最大键值
function table_maxn(t)
local mn = 0
for k, v in pairs(t) do
if mn < k then
mn = k
end
end
return mn
end
-- 两表相加操作
mytable = setmetatable({ 1, 2, 3 }, {
__add = function(mytable, newtable)
for i = 1, table_maxn(newtable) do
table.insert(mytable, table_maxn(mytable)+1,newtable[i])
end
return mytable
end
})
secondtable = {4,5,6}
mytable = mytable + secondtable
for k,v in ipairs(mytable) do
print(k,v)
end
以上实例执行输出结果为:
1 1
2 2
3 3
4 4
5 5
6 6
add 键包含在元表中,并进行相加操作。 表中对应的操作列表如下:(**注意:******是两个下划线)
模式 | 描述 |
---|---|
__add | 对应的运算符 '+'. |
__sub | 对应的运算符 '-'. |
__mul | 对应的运算符 '*'. |
__div | 对应的运算符 '/'. |
__mod | 对应的运算符 '%'. |
__unm | 对应的运算符 '-'. |
__concat | 对应的运算符 '...'. |
__eq | 对应的运算符 '=='. |
__lt | 对应的运算符 '<'. |
__le | 对应的运算符 '<='. |
__call 元方法
__call 元方法在 Lua 调用一个值时调用。以下实例演示了计算表中元素的和:
实例
lua
-- 计算表中最大值,table.maxn在Lua5.2以上版本中已无法使用
-- 自定义计算表中最大键值函数 table_maxn,即计算表的元素个数
function table_maxn(t)
local mn = 0
for k, v in pairs(t) do
if mn < k then
mn = k
end
end
return mn
end
-- 定义元方法__call
mytable = setmetatable({10}, {
__call = function(mytable, newtable)
sum = 0
for i = 1, table_maxn(mytable) do
sum = sum + mytable[i]
end
for i = 1, table_maxn(newtable) do
sum = sum + newtable[i]
end
return sum
end
})
newtable = {10,20,30}
print(mytable(newtable))
以上实例执行输出结果为:
70
__tostring 元方法
__tostring 元方法用于修改表的输出行为。以下实例我们自定义了表的输出内容:
实例
lua
mytable = setmetatable({ 10, 20, 30 }, {
__tostring = function(mytable)
sum = 0
for k, v in pairs(mytable) do
sum = sum + v
end
return "表所有元素的和为 " .. sum
end
})
print(mytable)
以上实例执行输出结果为:
表所有元素的和为 60