最近在研究一些使用Lua脚本的Unity项目, Lua主要用来实现频繁变更的业务逻辑,方便和美术资源一起进行在线热更新。一直以来主要从事游戏客户端的开发,实践应用Lua的情景比较少(相对于服务器的C++&Lua的技术栈),所以在初步的学习了解阶段做一些笔记。
语法
判断操作符
与/或:and表示与,or表示或。
~=/==:数值和字符串类型比较时是值比较(其他数据类型比较的是引用)。
没有三目运算符,可以采用(a and b) or c,不过由于逻辑判断只有在false和nil时为假,其余均为真,所以最好不这样写,理解起来有些费劲。
非全局方法访问操作符
obj. func 对象方法,类似其他语言的静态方法,传递的参数个数为显式的个数。
obj: func 对象成员方法,类似其他语言的成员方法,省去了方法的self参数声明和方法的显式调用(对象成员的方法定义 function obj:func() end,否则造成参数匹配错位)。
其他操作符
.. 字符串的连接符,+左右作用对象会被自动转义成数值类型进行相加运算。
# 长度运算符,可计算字符串(字符数组)和table的长度(仅统计所有下标为整数的元素的个数)。
table
既是数组又是hashmap。
遍历方式
- pairs 键值对遍历,可理解为其他的语言的foreach
- *ipairs:连续的整形键值,且value非空的table遍历。完全是为了体现语义精确的精神,不然就用pairs好了
- for i = 1, len, do 顺序
- for i = len, 1, -1 do 倒序
ps1:t[1] 和 t[“1”]表示不同的记录,即键值可以为不同的类型,非泛型。
ps2:索引下标从1开始,而不是0。这让我想起初学程序时对0索引值的不解,1不是更贴近自然表达么,不过现在反而觉得1作为下标有点特立独行。
metatable 元表与面向对象
metatable也是table
-- 定义UI基类:UIBase ------------------------------ UIBase = {} function UIBase:New(o) local o = o or {} -- 设置元表 setmetatable(o, self) -- 设置元表的元方法,指向表或者对应的方法 self.__index = self return o end function UIBase:Close() end function UIBase:Show() end function UIBase:Hide() end function UIBase:IsExist() return self~=nil and self.transform~= nil end -- 具体界面应用 ------------------------------------ UIAccount = UIBase:New() local this = UIAccount function this.ClickToClose() -- 调用基类的成员方法 this:Close() end
控制流
有break,没有continue。
return 必须紧接着end关键字,比如do return end,或者if true then return end。
支持可变参数
…为参数列表。
testobj = {} local this = testobj function this.TestArgs(...) print(...) local args = {...} print(#args) print(args[1]) print(args[2]) print(args[3]) print(args[4]) end this.TestArgs(1
,2,3,4)
支持多值返回
local function func() return 'a','b' end x,y = func() -- x='a', y='b' x,y,z = func() -- x='a', y='b',z=nil
local
变量声明除非有作为全局的必要,否则尽可能的使用local,运算效率更高。
优化
JIT即时编译技术,相当于给解释器增加缓存功能,对于热点代码做了编译缓存。