--
开头--[[
开头,]]--
结尾
- 在调试过程中如果想临时取消段注释,而直接将其标识删除,这样做其实并不好。因为有可能还需要再添加上。而段注释的写法相对较麻烦。所以,Lua 给出了一种简单处理方式:在开头的–[[前再加一个减号,即可使段注释不起作用。其实就是使两个段注释标识变为了两个行注释。
Lua 中有 8 种类型,分别为:nil、boolean、number、string、userdata、function、thread 和 table。
通过 type()
函数可以查看一个数据的类型
nil:只有值 nil 属于该类,表示一个无效值,与 Java 中的 null 类似。但在条件表达式中相当于 false。
boolean :包含两个值:false 和 true。
number: 表示双精度类型的实浮点数。
string:字符串,由一对双引号或单引号括起来。当一个字符串包含多行时,可以在第一行中以[[开头,在最后一行中以]]结尾,那么在[[与]]括起来的这多行内容就是一个字符串。换行符为字符串”\n”。
table :类似于 Java 中的数组,但比数组的功能更强大,更灵活。
function :由 C 或 Lua 编写的函数。
thread:协同线程,是协同函数的执行体,即正在执行的协同函数。
userdata:一种用户自定义数据,用于表示一种由应用程序或 C/C++ 语言库所创建的类型,可以将任意 C/C++ 的任意数据类型的数据存储到 Lua 变量中调用
- SciTE 对 Lua 支持的目前最高版本为 5.1,而整除运算符//需要在 Lua5.3 版本以上,所以当前 SciTE 中无法看到效果。
-- 定义一个普通函数 包含两个形参
function f1(a,b)print(a,b)
end
print("无实参传递")
f1()
print("传递一个实参")
f1(666)
print("传递两个实参")
f1(666,888)
print("传递三个实参")
f1(666,888,999)
-- 定义一个普通函数,包含可变参数
function f2(...)local a,b,c,d=...print(...)end
print("传递三个参数")
f2(10,20,30)
print("传递四个参数")
f2(10,20,30,40)
print("传递五个参数")
f2(10,20,30,40,50)
-- 定义一个函数,返回两个值
function f3(a,b)local sum=a+blocal mul=a*breturn sum,mul;
end
-- 一次性接受两个值
m,n=f3(10,10)
print("一个函数返回多个值")
print(m,n)
-- 定义两个普通函数
function sum(m,n)return m+n
end
function mul(m,n)return m*n
end
function complex(m,n,fun)local result=fun(m,n)print(result)
end
-- 普通调用
complex(3,4,sum)
complex(3,4,mul)
-- 匿名函数调用
complex(3,4,function(a,b)return a-b;end
);
a=10
if a>9 thenprint("num>0")
elseif num==0 thenprint("num = 0")
elseprint("num<0")
end
elseif
来做 if
嵌套语句。注意,不能使用 else
与 if
两个关键字的联用形式,即不能使用 else if
来嵌套 if
语句a=10
if a>9 thenprint("num>0")
elseif num==0 thenprint("num = 0")
elseprint("num<0")
end
while...do
score=450
while score>= 425 doprint("过了")score=score-1
end
repeat...until
score=450
repeatprint(score)score=score+1
until score>=427
数值 for
for var=exp1, exp2, exp3 do--循环体
end
for i=10,60,10 doprint(i)
end
泛型 for
-- 遍历emp中所有数组元素
for k,v in ipairs(emp) doprint(k,v)
end
break
goto
- Lua5.1 中不支持双冒号的语句标记。
-- 声明一个空的数组
arr={}
for i=1,3 do-- 声明空数组arr[i]={}for j=1,3 doarr[i][j]=i*jend
end
for i=1,3 dofor j=1,3 doprint(arr[i][j])end
end
-- 定义一个map
emp={name="张三",age=23,depart="销售"}
-- 通过下标方式操作
emp["gender"]="男"
print(emp["name"])
print(emp["gender"])
emp.workAge=3
print(emp.workAge)
print(emp.name)
-- 定义一个数组,map混合结构
emps={{name="001",age=11},{name="002",age=12},{name="003",age=13},{name="004",age=14}
}
for i=1,4 doprint(emps[i].name..":"..emps[i].age)
end
table.concat()
table.concat (table [, sep [, start [, end]]]):
table.unpack()
table.unpack (table [, i [, j]])
table.pack()
table.pack (...)
table.maxn()
table.maxn(table)
table.insert()
table.insert (table, [pos,] value)
table.remove ()
table.remove (table [, pos])
table.sort()
table.sort(table [,fun(a,b)])
- 如果 arr 中的元素既有字符串又有数值型,那么对其进行排序会报错。
- 如果数组中多个元素相同,则其相同的多个元素的排序结果不确定,即这些元素的索引顺序不确定。
- 如果数组元素中包含 nil,则排序会报错。
pairs(table)
与 ipairs(table)
。这两个迭代器通常会应用于泛型 for循环中,用于遍历指定的 table。这两个迭代器的不同是: ipairs(table)
:仅会迭代指定 table 中的数组元素。pairs(table)
:会迭代整个 table 元素,无论是数组元素,还是 key-value。emp={"apple",type="fruit",health="true",yieldly="east","banana","tangerine","grape"}
print(table.concat(emp,",",2))
print(table.concat(emp,",",2,3))
-- 遍历emp中所有数组元素
for k,v in ipairs(emp) doprint(k,v)
end
-- 遍历emp中所有的元素
for k,v in pairs(emp) doprint(k,v)
end
rectangle.lua
-- 声明一个模块
rectangle={}--为模块添加一个变量
rectangle.pi = 3.14--为模块添加函数(求周长)
function rectangle.perimeter(a, b)return (a+b)* 2
end--以匿名函数方式为模块添加一个函数(求面积)
rectangle.area = function(a,b)return a*b
end--定义与模块无关的内容-- 定义一个全局变量
goldenRatio=0.618--定义一个局部函数(求圆的面积)
local function circularArea(r)return rectangle.pi*r*r
end--定义一个全局函数(求矩形中最大圆的面积)
function maxcircularArea(a,b)local r=math.min(a,b)return circularArea(r)
endreturn rectangle
-- 导入模块
rect=require "rectangle"
-- 访问模块的属性,调用模块的函数
print(rectangle.pi)
print(rectangle.perimeter(3,5))
print(rectangle.area(3,5))print(rect.perimeter(3,5))
print(rect.area(3,5))
-- 访问模块中与模块无关的内容
print(goldenRatio)
print(maxcircularArea(3,5))
setmetatable(table,metatable)
:将 metatable 指定为普通表 table 的元表。getmetatable(table)
:获取指定普通表 table 的元表。_ _index
元方法。该重写的方法可以是一个函数,也可以是另一个表。如果重写的_ _index
元方法是函数,且有返回值,则直接返回;如果没有返回值,则返回 nil
。-- 以函数方式重写__index方法
emp={"apple",type="fruit",health="true",yieldly="east","banana","tangerine","grape"}
print(emp.x) --nil--声明一个元表
meta ={};
--将原始表与元表相关联
setmetatable(emp , meta)--有返回值的情况
meta._index = function(tab,key)return (key.."值不存在")
end--无返回值的情况
meta.__index =function(tab, key)print("通过["..key.."]访问的值不存在")
endprint(emp.x) --nil
print(emp[2]) --banana
emp2={"apple",type="fruit",health="true",yieldly="east","banana","tangerine","grape"}
print(emp2[5]) --nil
--声明一个元表
meta2={}
--将原始表与元表相关联
setmetatable(emp2,meta2)--再定义一个普通表
others={}
others[5]="strawberry"
others[6]="ananas"-- 指定元表为另一个普通表
meta2.__index=others--在原始表中若找不到,则会到元表指定的普通表中查找
print(emp2[5]) --strawberry
_ _newindex
元方法。该重写的方法可以是一个函数,也可以是另一个表。如果重写的_ _newindex
元方法是函数,且有返回值,则直接返回;如果没有返回值,则返回 nil
。emp3={"apple",type="fruit",health="true",yieldly="east","banana","tangerine","grape"}
print(emp3[5]) --nil
--声明一个元表
meta3={}
--将原始表与元表相关联
setmetatable(emp3,meta3)
-- 无返回值的情况
function meta3.__newindex(tab,key,value)print(key..":"..value)-- 将新增的key-value写入到原始表rawset(tab,key,value)
endemp3.x="ming"
print(emp3.x) -- ming
emp4={"apple",type="fruit",health="true",yieldly="east","banana","tangerine","grape"}
print(emp4[5]) --nil--声明一个元表
meta4={}
--将原始表与元表相关联
setmetatable(emp4,meta4)
-- 定义一个普通表
other4={}
-- 元表指定额另一个普通表的作用是,暂存新增的数据
meta4.__newindex=other4
emp4.x="ming"
print(emp4.x) --nil
print(other4.x) --ming
_ _add
元方法,而具体的运算规则,则是定义在该重写的元方法中的。这样,当一个 table 在进行加法(+)运算时,就会自动调用其元表的_ _add
元方法-- 运算符元方法
emp5={"apple",type="fruit",health="true",yieldly="east","banana","tangerine","grape"}
-- 声明一个元表
meta5={__add=function(tab,num)-- 遍历tab中的所有元素for k,v in pairs(tab) do--若value为数值类型,做算数运算if type(v)=="number" thentab[k]=v+num--若value为string,做字符拼接elseif type(v)=="string" thentab[k]=v..numendend-- 返回变化后的tablereturn tabend
};--将原始表与元表相关联
setmetatable(emp5,meta5)
emp5=emp5+5for k,v in pairs(emp5) doprint(k.." : "..v)
end
元方法 | 说明 |
---|---|
__add | 加法,+ |
__sub | 减法,- |
__mul | 乘法,* |
__div | 除法,/ |
__mod | 取模,% |
__pow | 次幂,^ |
__unm | 取反,- |
__idiv | 取整除法,// |
__lt | 小于,< |
__concat | 字符串连接,… |
__len | 字符串长度,# |
__band | 按位与,& |
__bor | 按位或, |
__bxor | 按位异或,~ |
__bnot | 按位非,~ |
__shl | 按位左移,<< |
__shr | 按位右移,>> |
__eq | 等于,== |
__le | 小于等于,<= |
table
的存放地址。如果想让其输出 table中的内容,可重写_ _tostring
元方法-- __tostring方法
emp6={"apple",type="fruit",health=1,yieldly="east","banana","tangerine","grape"}
-- 声明一个元表
meta6={__add=function(tab,num)-- 遍历tab中的所有元素for k,v in pairs(tab) do--若value为数值类型,做算数运算if type(v)=="number" thentab[k]=v+num--若value为string,做字符拼接elseif type(v)=="string" thentab[k]=v..numendend-- 返回变化后的tablereturn tabend, -- 这里需要加上一个逗号__tostring=function(tab)str=""--字符串拼接for k,v in pairs(emp6) dostr=str.." "..k..":"..vendreturn strend
};-- 将原始表与元表相关联
setmetatable(emp6,meta6)emp6=emp6+10
print(emp6)
_ _call
元方法。该用法主要是可以简化对 table 的相关操作,将对 table 的操作与函数直接相结合。-- __call方法
emp7={"apple",type="fruit",health=1,yieldly="east","banana","tangerine","grape"}
-- 将原始表与元表相关联 匿名函数
setmetatable(emp7,{__call=function(tab,num,str)-- 遍历tablefor k,v in pairs(tab) do--若value为数值类型,做算数运算if type(v)=="number" thentab[k]=v+num--若value为string,做字符拼接elseif type(v)=="string" thentab[k]=v..numendendreturn tabend
})newemp=emp7(5,"-hello")
for k,v in pairs(newemp) doprint(k..":"..v)
end
简单对象的创建
-- 简单对象的创建
-- 创建一个animal对象
animal={name="Tom",age=3,
say=function(voice)print(animal.name.."正在"..voice.."叫")
end}
-- 添加方法
animal.run=function(speed)print(animal.name.."正在以"..speed.."m/s前进")
end
animal.say("喵喵")
animal.run(5)
-- 创建对象的指针,观察是否指向同一个对象
animal2=animal
-- 打印对象的名字和地址
print(animal2.name, animal2)
print(animal.name, animal)-- self代表当前的实例
-- 冒号中会自动包含一个self参数,相当于this
function animal:play(games)print(self.name.."正在玩"..games.."游戏")
end
-- 将animal置空
animal=nil
animal2.name="philips"
animal2:play("捉迷藏")
类的创建
_ _index
元方法,且将基础表指定为重写的_ _index
元方法。由于 new()中的表是空表,所以用户访问的所有 key 都会从基础类(表)中查找。-- 创建类
Animal={name="no_name",age=1}
function Animal:bark(voice)print(self.name..voice.."叫")
end
-- 为该类添加一个无参构造器
function Animal:new()-- 创建一个空表local a={}-- 为新表指定元素为当前基类表-- 如果后续操作,没有在a表中找到相关的数据,就从Animal表中查找,如果Animal中也没有就返回空setmetatable(a,{__index=self})-- 返回新表return a
endanimal01=Animal:new()
animal02=Animal:new()
print(animal01)
print(animal02)-- 给表a属性赋值
animal01.name="TOM"
animal01.age=3
animal01.type="猫"
--
print(animal01.name.."是一只"..animal01.age.."岁的"..animal01.type)function animal02:skill()return "我会捉老鼠"
end
print(animal02.name..animal02.age.."岁,"..animal02.skill())
-- 类的继承
BaseAnimal={name="no_name",age=1}
function BaseAnimal:bark(voice)print(self.name..voice.."叫")
end
-- 为该类添加一个无参构造器
function BaseAnimal:new()-- 创建一个空表local a={}-- 为新表指定元素为当前基类表-- 如果后续操作,没有在a表中找到相关的数据,就从Animal表中查找,--如果Animal中也没有就返回空setmetatable(a,{__index=self})-- 返回新表return a
end-- 为该类添加一个带参构造器
function BaseAnimal:new(obj)local a=obj or {}setmetatable(a,{__index=self})-- 返回新表return a
endanimal03=BaseAnimal:new()
-- 调用带参构造器 实参为一个匿名表
animal04=BaseAnimal:new({type="猫"})animal04.name="jerry"
animal04.age=3
print(animal04.name.." : "..animal04.age.."岁,"..animal04.type)--为Animal类创建一个子类cat
cat = BaseAnimal:new({type="波斯猫"})
cat.eyes ="蓝眼睛"tomcat = cat : new()
tomcat.name = "Tom"print(tomcat.name.."是"..tomcat.eyes.."的"..tomcat.type)
-- 协同线程
-- 创建一个协同线程实例
crt=coroutine.create(function(a,b)print(a,b,a+b)-- 获取正在运行的协同线程的实例,thread类型tr=coroutine.running();print(tr)-- 查看协同线程实例的类型print(type(tr))-- 查看系统线程实例的状态print(coroutine.status(crt))-- 将当前协同线程实例挂起coroutine.yield()print("线程又重新返回到了协同线程")end
)-- 启动协同线程实例
coroutine.resume(crt,3,5)-- 查看crt类型
print("main-"..type(crt))-- 查看协同线程实例的状态
print("main-"..coroutine.status(crt))--继续执行协同线程
coroutine .resume (crt, 3,5)--查看协同线程实例的状态
print ( "main-"..coroutine.status (crt))
-- 创建一个协同线程实例
crt2=coroutine.create(function(a,b)print(a,b)-- 将当前线程挂起,同时携带两个返回值coroutine.yield(a*b,a/b)print("线程又重新返回到了协同线程")-- 返回两个值return a+b,a-bend
)
--启动协同线程,返回三个值
--第一个返回值为协同线程启动成功状态
--后面的返回值为内置函数的返回值
success1, resu1t1,result2 = coroutine.resume(crt2,12,3)print(success1,resu1t1,result2)success2,result1,result2 = coroutine.resume(crt2)
print(success2,result1,result2)
-- 协同函数--创建一个协同函数
cf =coroutine.wrap(function(a,b)print(a,b)-- 获取当前协同函数创建的协同线程tr=coroutine.running()print("tr的类型为:"..type(tr))-- 挂起当前的协同线程-- 也可以添加返回的参数,如返回协同线程的实例-- coroutine.yield(coroutine.running(),a+1,b+1)coroutine.yield(a+1,b+1)print("线程又重新返回到了协同线程")return a+b,a*bend
)
-- 调用协同函数,启动协同线程
result1,result2=cf(3,5)
print(result1,result2)print("cf的类型为:"..type(cf))-- 重启挂起的协同线程result1,result2=cf(3,5)
print(result1,result2)--[[
-- 调用协同函数,启动协同线程
cftr,result1,result2=cf(3,5)
-- 重启挂起的协同线程
success,result1,result2=coroutine.resume(cftr)]]--
io.open (filename [, mode])
io.input (file)
io.output (file)
io.read([format])
io.write(data)
file:seek ([whence [, offset]])