StarryNights

每一个你所后悔的现在,都有一个不够努力的曾经

站内检索

循着字句,邂逅星光

搜索文章标题与正文,直达命中的章节

开始一次轻盈的站内探索

从这些主题开始探索

输入关键词

可同时输入多个词语缩小范围

发现内容

在摘要中查看高亮的关键词

快速直达

点击文章或章节标题继续阅读

# 引言

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表示执行的独立线路, 用于执行协同程序
tableLua 中的表(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, 逻辑非为 falsenot (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这个操作符的优先级由高到低如下表

operlevel
^8
not - (unary)7
* / %6
+ -5
..4
> < >= <= ~= ==3
and2
or1

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")
end

while 和其他语言一样, Lua 先测试 while 的条件, 直到条件为假才终止, 否则循环执行循环体之内的代码

local i = 1
while a[i] do
    print(a[i])
    i = i + 1
end

repeat 和它的名字一样, 一条 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== 逃 ~~

更新于 阅读次数 — 次
STARRY NIGHTSPERSONAL NOTES

赞赏

文章至此,故事还在继续。

Seiun

长按或右键保存收款码