# 引言
lua 作为一种简单、可扩展、可移植及高效的脚本语言, 广泛地被用于网络游戏以及手机游戏中。写游戏常常需要跟 lua 打交道, 还是做些笔记记下来, 当做备忘, 方便以后没事翻一翻
# 官方文档
在开始吹逼之前先放一下官方文档, 毕竟官方的东西还是挺权威的 [http://www.lua.org/manual/][http://www.lua.org/manual/]
点击对应版本就可以看相关的 api 文档或者介绍了
# 一、类型与值
lua 中有8种基础类型如下表所示
| 数据类型 | 描述 |
|---|---|
nil | 这个最简单, 只有值 nil 属于该类, 表示一个无效值(在条件表达式中相当于 false) |
boolean | 包含两个值: false 和 true |
number | 表示双精度类型的实浮点数 |
string | 字符串由一对双引号或单引号来表示 |
function | 由 C 或 Lua 编写的函数 |
userdata | 表示任意存储在变量中的 C 数据结构 |
thread | 表示执行的独立线路, 用于执行协同程序 |
table | Lua 中的表(table) 实是一个"关联数组" (associative arrays), 数组的索引可以是数字或者是字符串。在 Lua 里, table 的创建是通过 "构造表达式" 来完成, 最简单构造表达式是 {}, 用来创建一个空表。 |
以下是 Lua 的变量的定义方式, 区别在于未使用 local 关键字声明的变量将会是全局变量, 而使用了 local 关键字声明的变量是局部变量, 其余的 .lua 文件将不能顺利地访问。
local str = "hello wprld"
lcoal num = 10
local flag = false
arg = "lua"
a = nil
b = 12
print(c) --> nil# 二、表达式
# 算术运算符
Lua支持的常规的运算符如下, 假设 A = 10, B = 20
| 操作符 | 描述 | 实例 |
|---|---|---|
+ | 加法 | A + B 输出结果 30 |
- | 减法 | A - B 输出结果 -10 |
* | 乘法 | A * B 输出结果 200 |
/ | 除法 | A / B 输出结果 2 |
% | 取余 | B % A 输出结果 0 |
^ | 乘幂 | A^2 输出结果 100 |
- | 负号 | -A 输出结果 -10 |
Hint: 这儿的 ^ 是右结合运算符, 即 2^3^2 结果是 512 而不是 64
# 关系运算符
下表列出了 Lua 语言中的常用关系运算符, 同样设定 A = 10, B = 20
| 操作符 | 描述 | 实例 |
|---|---|---|
== | 等于, 检测两个值是否相等, 相等返回 true, 否则返回 false | (A == B) 为 false |
~= | 不等于, 检测两个值是否相等, 相等返回 false, 否则返回 true | (A ~= B) 为 true |
> | 大于, 如果左边的值大于右边的值, 返回 true, 否则返回 false | (A > B) 为 false |
< | 小于, 如果左边的值大于右边的值, 返回 false, 否则返回 true | (A < B) 为 true |
>= | 大于等于, 如果左边的值大于等于右边的值, 返回 true, 否则返回 false | (A >= B) 返回 false |
<= | 小于等于, 如果左边的值小于等于右边的值, 返回 true, 否则返回 false | (A <= B) 返回 true |
# 逻辑运算符
下表列出了 Lua 语言中的常用逻辑运算符, 设定 A = true, B = false
| 操作符 | 描述 | 实例 |
|---|---|---|
and | 逻辑与操作符。 若 A 为 false, 则返回 A, 否则返回 B | (A and B) 为 false |
or | 逻辑或操作符。 若 A 为 true, 则返回 A, 否则返回 B | (A or B) 为 true |
not | 逻辑非操作符。与逻辑运算结果相反, 如果条件为 true, 逻辑非为 false | not (A and B) 为 true |
代码示例
print(4 and 5)
print(nil and 3)
print(false ans 13)
print(4 or 5)
print(false or 5)
-- output
5
nil
false
4
5一些Lua的习惯性写法 --> 表示等价
a = a or b --> if not a then a = b end
(a and b) or c --> C语言中a ? b = c (当然使用前提为b不为假)# 其他运算符
即连接运算符与计算表或字符串长度的运算符如下表
| 操作符 | 描述 | 实例 |
|---|---|---|
.. | 连接两个字符串 | a..b, 其中 a 为 "Hello " , b 为 "World", 输出结果为 "Hello World"。 |
# | 一元运算符, 返回字符串或表的长度 | #"Hello" 返回 5 |
代码示例
print("hello " .. "world")
local num = 111
print("num = " .. num) --> 在字符连接时lua会自动进行类型转换
-- output
hello world
num = 111# 运算符优先级
LUa这个操作符的优先级由高到低如下表
| oper | level |
|---|---|
^ | 8 |
not - (unary) | 7 |
* / % | 6 |
+ - | 5 |
.. | 4 |
> < >= <= ~= == | 3 |
and | 2 |
or | 1 |
Hint: 除了 ^ 和 .. 所有的二元运算符都是左连接的
代码示例
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)# table构造式
table 作为 lua 中唯一的数据结构, 还是有点意思的, 构造式就是用于创建和初始化 table 的表达式
最简单的就是一个空构造式 {}
按照风格划分, lua的 table 构造式大致可以分为如下两种
- 记录风格:
a = {x=10, y=20}代码等价于a = {} a.x = 10, a.y = 20 - 列表风格:
days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
当然两种风格在实际的使用中经常混用, 这个是完全没有问题的, 记录风格的访问类似于C中结构体一样访问, 比如 a.x, 列表风格就和数组一样的访问形式
# 三、语句
# 赋值语句
赋值的基本含义就是指修改一个变量和 table 中的字段的值(在 lua 中没有经过复赋值的变量, 默认值都是 nil)
a = "hello" .. "world"
t.n = t.n + 1
此外, Lua 还支持 "多重赋值", 每个变量由 , 分隔, 如 a, b = 10, 2*x
在多重赋值中, Lua 会先对等号右边的所有元素求值, 然后才执行赋值, 并且赋值讲究 多弃少补 的原则, 数量多余的舍弃, 数量不足用 nil 赋值, 比如下列语句都是合法的
a, b = b, a
a, b, c = 1, 2, 3, 4
a, b, c = 1, 2# 局部变量与块
相对与全局变量 lua 还提供了局部变量, 用关键字 local 来创建, 作用域仅限于申明他们的那个块, 一个块可以是一个控制结构的执行体, 或者是函数的执行体或者是一个程序块, 这一点和其他的变成语言并没有什么不同。
当然尽可能的使用局部变量是一个好的编程习惯, 可以有效避免将一些无用的变量名称引入全局环境, 避免了搞乱全局环境。
# 控制结构
在 lua 中有以下几种控制结构, 是编程语言这些都大同小异, 下面就直接以代码例程形式给出了
if then else 先对 if 条件求值, 根据测试结果执行 then 或者 else 部分
if a < 0 then a = 0 end
if a < b then return a else return b end
if line > MAXLINES then
showpage()
line = 0
end
-- 当然多重嵌套的if也是可以的, lua可以直接使用elseif
if op == "+" then
r = a + b
elseif op == "-" then
r = a - b
elseif op == "*" then
r = a * b
elseif op == "/" then
r = a / b
else
print("option is illegal")
endwhile 和其他语言一样, Lua 先测试 while 的条件, 直到条件为假才终止, 否则循环执行循环体之内的代码
local i = 1
while a[i] do
print(a[i])
i = i + 1
endrepeat 和它的名字一样, 一条 repeat-until 语句重复执行循环体直到条件为真时结束
-- 打印输入的第一行不为空的内容
repeat
line = io.read()
until line ~= ""
print(line)数字型for & 泛型for
-- 数字型
for i = 1, 10 do
print(i)
end
-- 泛型for, 使用pair和ipair迭代遍历table中的内容
local t1 = {
["str"] = {"str1", "str2", nil, "lua"},
["num"] = {1, 2, 3, 4}
}
local t2 = {
[1] = {"str1", "str2", nil, "lua"},
[2] = {1, 2, 3, 4}
}
print("------------------------")
for k, v in pairs(t1) do
print(k)
for k1, v1 in pairs(t1[k]) do
print(v1)
end
end
print("////////////////////////")
for k, v in pairs(t2) do
print(k)
for k1, v1 in pairs(t2[k]) do
print(v1)
end
end
print("=========================")
for i, v in ipairs(t1) do
print(i)
for k, v in ipairs(t1[i]) do
print(v)
end
end
print("+++++++++++++++++++++++++")
for i, v in ipairs(t2) do
print(i)
for k, v in ipairs(t2[i]) do
print(v)
end
end
-- output
------------------------
num
1
2
3
4
str
str1
str2
lua
////////////////////////
2
1
2
3
4
1
str1
str2
lua
=========================
+++++++++++++++++++++++++
1
str1
str2
2
1
2
3
4
-- 可以看出ipairs对于key值为string的时候无法进行迭代, 并且迭代过程中遇到nil即终止
-- pairs 则不会有这种情况, pairs遍历table所有元素, 但并不一定有序break 与 return
local i = 1
while a[i] do
if a[i] == v then break end
i = i + 1
end
function foo()
return -->> 错误语法
do return end -->> ok# 结语
关于函数这些, lua的库这些就在以后的博客中, 在介绍吧, 这篇博客就酱紫 Orz== 逃 ~~

有什么想法,欢迎留下评论。