Lua要点
Lua是一种轻量的脚本解释语言,在游戏开发中多被用于实现需要进行热更新的逻辑。
热更新:在不关闭游戏的情况下对游戏数据(素材、脚本)进行更新。由于不需要用户重新下载整个游戏,可以防止用户流失。
Lua热更新原理:将Lua代码文件作为文本素材下载以后,运行过程中即时解释运行,无需重新编译。
全局变量:
Lua变量默认为全局变量,无需修饰符,读取一个未声明的全局变量会返回空值nil
局部变量:
局部变量需要local修饰符,在不同位置声明,有不同的作用范围
变量名称使用字母或下划线开头
Lua保留关键字,不能用于变量名
and break do else elseif
end false for function if
in local nil not or
repeat return then true until
while
Lua是大小写敏感的
Lua使用双横线--作为注释符号,--[[ 和 ]]--作为块注释符号
--[[
print(10) -- 这句代码不会执行
]]--
Lua有8种基本数据类型:nil, boolean, number, string, userdata, function, thread, table
Lua将nil和false视作布尔逻辑false,其余数据都视为true(包括0)
Lua没有区分整数和浮点数,以下都是合法的数字表述:4, 0.4, 4.57e-3, 0.3e12, 5e+20
Lua字符串:
a = "a line"
b = 'another line'
使用 [[ 和 ]] 定义字符串块
page = [[
<HTML>
<HEAD>
<TITLE>An HTML Page</TITLE>
</HEAD>
<BODY>
<A HREF="http://www.lua.org">Lua</A>
[[a text between double brackets]]
</BODY>
</HTML>
write(page)
两个小数点是字符串连接符 ..
print(“Hello” .. “ World”) --> Hello World
变量的多重赋值:在一条语句内为多个变量赋值
a, b, c = 0, 1
print(a,b,c) --> 0 1 nil
a, b = a+1, b+1, b+2 -- b+2的值被忽略
print(a,b) --> 1 2
a, b, c = 0
print(a,b,c) --> 0 nil nil
利用变量的多重赋值,可以简单地实现两个变量值的交换
x, y = y, x -- 交换x 和 y
a, a[j] = a[j], a -- 交换a 和 a[j]
Lua提供的唯一的数据集合是Table(表),表存放的是键值对,类似于C#的字典
a = {} -- 创建一个空白的表,a是指向这个表的引用变量
k = "x"
a[k] = 10 -- 往表中添加一个新键值对,键是k变量存放的值(字符x),值是10
a[20] = "great" -- 往表中添加一个新键值对,键是20,值是字符串great
print(a["x"]) --> 10
k = 20
print(a[k]) --> "great"
a["x"] = a["x"] + 1 -- 把字符x对应的值加一
print(a["x"]) --> 11
也可以用以下写法访问表中的元素:
a.x = 10 -- 相当于 a["x"] = 10
print(a.x) -- 相当于 print(a["x"])
print(a.y) -- 相当于 print(a["y"])
表的初始化:
只填入元素的值,键会自动从1开始排列(不是从0开始)
days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
print(days[4]) --> Wednesday
元素的值可以通过函数的返回值获得
tab = {sin(1), sin(2), sin(3), sin(4),sin(5), sin(6), sin(7), sin(8)}
下面的两种初始化方式是等价的
a = {x=0, y=0}
a = {}; a.x=0; a.y=0
往表中存入1000个键值对的写法:
a = {} -- 创建空表
-- 创建1000个键值对
for i=1,1000 do a = i*2 end
print(a[9]) --> 18
a["x"] = 10
print(a["x"]) --> 10
print(a["y"]) --> 没有这个键,返回nil
Lua中一般把1作为第一个元素的编号(不是0)
关系运算符:< > <= >= == ~=
逻辑运算符:and,or,not
print(4 and 5) --> 5
print(nil and 13) --> nil
print(false and 13) --> false
print(4 or 5) --> 4
print(false or 5) --> 5
print(not nil) --> true
print(not false) --> true
print(not 0) --> false
print(not not nil) --> false
流程控制语句:
if … then … else … end
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 … then … elseif … then … end
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
error("invalid operation")
end
while ... do … end
local i = 1
while a do
print(a)
i = i + 1
end
repeat … until …
repeat
line = os.read()
until line ~= ""
print(line)
for ... do ...
for i=1,f(x) do print(i) end
for i=10,1,-1 do print(i) end
local found = nil
for i=1,a.n do
if a == value then
found = i
break
end
end
print(found)
泛型for(使用for遍历Table)
-- 输出名为a的Table的所有键值对
for i,v in pairs(a) do print(i, v) end
-- 输出名为t的Table的所有键值对的键
for k in pairs(t) do print(k) end
--只输出t的Table的数组部分(以整数为键的元素)所有键值对的键
for k in ipairs(t) do print(k) end
break 和 return
break用于中断循环,return用于返回运行结果
Lua中的break和return只能放在代码块的最后,否则会产生语法错误
正确:
local i = 1
while a do
if a == v then break end
i = i + 1
end
错误:
function foo ()
return --<< return不是代码块的最后一句,语法错误
-- 下面这句,用一个do代码块包住return,就不会有语法错误
do return end -- OK
... -- return后面的代码都不会执行了
end
Lua的函数
函数的调用写法
print(8*9, 9/8)
a = math.sin(3) + math.cos(10)
print(os.date())
调用函数时,如果参数只有一个,并且参数是字符串或者表的初始化语句,可以省略括号
print "Hello World" <--> print("Hello World")
dofile 'a.lua' <--> dofile ('a.lua')
print [[a multi-line <--> print([[a multi-line
message]] message]])
f{x=10, y=20} <--> f({x=10, y=20})
type{} <--> type({})
函数的定义格式
-- 把数组a的所有元素累加
function add (a)
local sum = 0
for i,v in ipairs(a) do
sum = sum + v
end
return sum
end
调用函数时如果省略参数,参数会被视为nil
function incCount (n)
n = n or 1
count = count + n
end
当n被省略时,n = n or 1 = nil or 1 = 1,每次调用count会加一。
函数可以返回多个返回值
function foo2 () return 'a','b' end -- 返回两个结果
可以使用多个变量接收函数的多个返回值
x, y = foo2() -- x='a', y='b'