Lua 学习记录-2
数组
1. 一维数组:
array = {"1","2","3"}
和java的一维数组用法相似
2. 多维数组:
在 Lua 索引值是以 1 为起始,但你也可以指定 0 开始,除此外我们还可以以负数为数组索引值。
注:数组设定了指定的索引值,这样可以避免出现 nil 值,有利于节省内存空间。
table
区分大小写(Lua对大小写敏感)
a=5 -- 全局变量
local b=5 -- 局部变量
声明:
1. A~Z
2. a~z
3. _
4. 0~9
注:最好不要使用下划线加大写字母的标示符,因为Lua的保留字也是这样的。
pairs ipairs (迭代器)###
pairs可以遍历表中所有的key,并且除了迭代器本身以及遍历表本身还可以返回nil;
但是ipairs则不能返回nil,只能返回数字0,如果遇到nil则退出。它只能遍历到表中出现的第一个不是整数的key
eg:
table1 = {}
table1[1] = "1"
table1[2] = "2"
table1[4] = "4"
for i, v in pairs(table1) do
print(i,v)
end
print("-----")
for i, v in ipairs(table1) do
print(i,v)
end
结果:
1 1
2 2
4 4
-----
1 1
2 2
模块和包
模块的本质就是一个table,它有自己的属性。类似于java中的对象,有成员变量、成员函数。模块的作用是将某一功能单独划分出来实现解耦。
-- 文件名为 module.lua
-- 定义一个名为 module 的模块
module = {}
-- 定义一个常量
module.constant = "这是一个常量"
-- 定义一个函数
function module.func1()
io.write("这是一个公有函数!\n")
end
local function func2()
print("这是一个私有函数!")
end
function module.func3()
func2()
end
return module
使用request加载
local a = require("module")
a.func1()
Lua元表
对table进行操作,改变table的行为,一般对table进行操作,table是不知道如何操作。例如两个表
函数 描述
__add 运算符 +
__sub 运算符 -
__mul 运算符 *
__div 运算符 /
__mod 运算符 %
__unm 运算符 -(取反)
__concat 运算符 ..
__eq 运算符 ==
__lt 运算符 <
__le 运算符 <=
__call 当函数调用
__tostring 转化为字符串
__index 调用一个索引
__newindex 给一个索引赋值
协同程序(coroutine)
类似于同步的多线程,利用resume和yield进行内外部数据传输(resume传入、yield传出)
1. coroutine.create()
创建coroutine,返回coroutine, 参数是一个函数,当和resume配合使用的时候就唤醒函数调用
2. coroutine.resume()
重启coroutine,和create配合使用
3. coroutine.yield()
挂起coroutine,将coroutine设置为挂起状态,这个和resume配合使用能有很多有用的效果
4. coroutine.status()
查看coroutine的状态。注:coroutine的状态有三种:dead,suspend,running,具体什么时候有这样的状态请参考下面的程序
5. coroutine.wrap()
创建coroutine,返回一个函数,一旦你调用这个函数,就进入coroutine,和create功能重复
6. coroutine.running()
返回正在跑的coroutine,一个coroutine就是一个线程,当使用running的时候,就是返回一个corouting的线程号
面向对象(数组+映射)
面向对象编程是我们常使用的一种计算机编程,在Lua中可以加入json,“Lua-json-数据传输”的解决方案
对象 = 属性 + 方法。Lua中最基本的结构是table,所以需要用table来描述对象的属性
-
成员变量
Table = {id=0,name=“unknown”,…}
Table.address = “China”
-
成员函数
初始化
function Table:new(o,"属性1","属性2",...) o = o or {} setmetatable(o,self) self.__index = self 属性1 = 属性1 or "" 属性2 = 属性2 or 0 ... self.属性1 = 属性1 self.属性2 = 属性2 ... return o end
成员函数
function MyObj:toString() print("属性1:"..Table.属性1) print("属性2:"..Table.属性2) ... end
-
继承、重写
继承的关键点是在基类中利用元表,setmetatable(o, self),学习完前人的一个例子后进行修改:
-- 冒号 :new(o) 代码可以省略 self ,在访问的时候object:new(o) -- 点号 :new(o) 改成 .new(self,o),在访问的时候 object.(object,o) 冒号默认第一个参数传入self ----基类 Account = { balance = 0}; function Account:new(o) o = o or {} setmetatable(o, self); --O 继承 self self.__index = self; --关联元表条目 return o; end function Account.deposit(self, v)--加钱 self.balance = self.balance + v; end function Account:withdraw(v)--减钱 if (v) > self.balance then error "insufficient funds"; end self.balance = self.balance - v; end ----创建子类,继承基类,重写父类方法,创建子类方法 SpecialAccount = Account:new(); function SpecialAccount:deposit(v) self.balance = self.balance + v end function SpecialAccount:withdraw(v) print("子类减钱") if v - self.balance >= self:getLimit() then error "insufficient funds"; end self.balance = self.balance - v; end function SpecialAccount.getLimit(self) return self.limit or 0; end ----实例化一个新的 SpecialAccount 对象 s = SpecialAccount:new { limit = 100.00,name = "Tom" }; print("1. limit = "..s.limit,"balance = "..s.balance); s:deposit(5) print("2. limit = "..s.limit,"balance = "..s.balance); s:withdraw(19) print("3. limit = "..s.limit,"balance = "..s.balance); s.withdraw(s,25) print("4. limit = "..s.limit,"balance = "..s.balance); s.deposit(s,60) print("5. limit = "..s.limit,"balance = "..s.balance); s.limit = 5 s:withdraw(50) print("6. limit = "..s.limit,"balance = "..s.balance);
结果
1. limit = 100 balance = 0 2. limit = 100 balance = 5 子类减钱 3. limit = 100 balance = -14 子类减钱 4. limit = 100 balance = -39 5. limit = 100 balance = 21 子类减钱 lua.exe: BaseLua.lua:71: insufficient funds stack traceback: [C]: in function 'error' BaseLua.lua:71: in function 'withdraw' BaseLua.lua:93: in main chunk [C]: ?