主要记录一些学习过程Lua基础知识
1.Lua中基本类型
nil(空), boolean(布尔) ,number(数值) ,string(字符串), function(函数), thread(线程), table(表)
print(type(nil)) --nil
print(type(true)) --boolean
print(type(3)) --number
print(type("Hello world")) --string
print(type(print)) --function
print(type(type)) --thread
print(type({})) --table
表示无效值 需要注意的是将nil赋值给全局变量相当于将其删除
true/false 特别注意的是在lua中把0和空字符串视为真
- 可以使用not逻辑运算符进行判断true/false
print(not 0)-- false 则0为真
print(not '')--false 则''为真
lua中整数和浮点型值的类型都是number类型
print(type(1)) --number
print(type(1.11)) --number
需要注意的一点是1.0后边的0不会自动抹去
print(3) --3
print(3.0) --3.0
lua中的string是不可变值 不能直接改变某个字符串中的某个字符
在lua中’ '和" "是等价的 需要注意的是字符串中的第一个字符索引为1
a="hello"
print(#a)--5
print(string.len(a))--5
a="hello"
a.." world" --hello world
print(a)--hello
print("5"+1)--6
a="hello"
print(string.rep(a,3))--hellohellohello
3.string.reverse(s,n) 获取字符串的翻转
print(string.reverse("hello"))--olleh
4.**string.lower(s)**将字符串中的大写字母都转换成小写函数string.upper(s)与其相反
5.string.sub(s,i,j) 从字符串s中提取第i个到第j个字符(包括第i个和第j个字符)
a="hello"
print(string.sub(a,2,4))--ell
print(a)--hello
print(string.sub(a,2,-2))--ell -2表示倒着数第二个字符
6.string.format() 对字符串格式化和将数值输出为字符串
a=10
b=11
str1="Hello"
str2="world"
print(string.format("a=%d b=%d",a,b))--a=10 b=11
print(string.format("%s%s",str1,str2))--Helloworld
7.string.find(s,t) 在s中查找t字符串 如果找到返回索引否则返回nil
str1="Hello"
print(string.find(str1,"ell"))--2 4
print(string.find(str1,'l')) --3 3 只能查找一个
print(string.find(str1,'aw')) --nil
8.string.gsub(s,t,w) 将s中的所有t字符串替换为w 返回替换后的字符串和替换次数
str1="Hello"
print(string.gsub(str1,'l','w'))--Hewwo 2
print(string.gsub(str1,'i','n'))--Hello 0
print(string.match("hello world","hw"))--nil
print(string.match("hello world","hello"))--hello
table(表)是Lua的一种数据结构可以用来创建数组,字典等 table中默认初始索引为1
1.表的构建
mytable={}--初始化表
mytable["str1"]="str"
mytable[2]=23;
print(mytable.str1) --str
print(mytable["str1"])--str
print(mytable[2]) --23
days={"str1","str2","str2"}
print(days[1]) --str1
2.遍历表
使用pairs迭代器遍历表
tab={"I",a=1,b=2,"as"}
for k,v in pairs(tab) do
print(k,v)
--1 I
--2 as
--a 1
--b 2
end
4.table标准库
tab={"I","asd","we","as"}
print(table.concat(tab,"."))--I.asd.we.as
print(table.concat(tab,".",2))--asd.we.as
print(table.concat(tab,".",2,3))--asd.we
tab={"I","asd","we","as"}
table.insert(tab,"xx")--默认插入末尾
for k,v in pairs(tab) do
io.write(v.." ")--I asd we as xx
end
table.insert(tab,1,"m")--插入首部
for k,v in pairs(tab) do
io.write(v.." ")--m I asd we as xx
end
tab={"I","asd","we","as","awqe"}
print(table.maxn(tab))--5
tab={"I","asd","we","as","awqe"}
table.remove(tab)--默认移除最后一个
for k,v in pairs(tab) do
io.write(v.." ")--I asd we as
end
table.remove(tab,2)
for k,v in pairs(tab) do
io.write(v.." ")--I we as
end
tab={12,3,2,4,6,44}
table.sort(tab)
for k,v in pairs(tab) do
io.write(v.." ")--2 3 4 6 12 44
end
table.sort(tab,function(a,b)
return a>b
end)
for k,v in pairs(tab) do
io.write(v.." ")--44 12 6 4 3 2
end
function functionName(...)
end
--匿名函数
function(...)
end
function Foo(a,b)
return a,b
end
a,b,c=Foo(10,11)--当接收参数大于返回参数时会对后续接收参数赋值为nil
print(a.." "..b) --10 11
print(c)--nil
b=nil
a=Foo(10,11) --按顺序进行接收未接收的数据进行舍弃
print(a)--10
function myF(...)
local a,b=...
print(a.." "..b)--1 2
end
myF(1,2,34,4)
function myF(...)
local a,b=...
print(select("#",...))--4
print(select(2,...))--2,34,4 返回第n个及以后的值
end
myF(1,2,34,4)
--闭包现象---
- [未理解原理]
在运行时,每当Lua执行一个形如function…end 这样的表达式时,就会创建一个新的数据对象,
其中包含了相应函数原型的引用及一个由所有upvalue引用组成的数组,而这个数据对象就称为闭包。
闭包是由一个函数和该函数会访问到的非局部变量(或者是upvalue)组成的
function myFunction()
local c=0
return function()
c=c+1--词法定界使子函数能够访问主函数的值
return c
end
end
c1=myFunction()
print(c1())--1
print(c1())--2
c2=myFunction()
print(c2())--1
print(c1())--3
> < >= <= == ~=(不等于)
a=false
b=10
c=1
d=nil
print(a and b) --false
print(c and b) --10
print(d and b) --nil
a=false
b=10
c=1
print(a or b) --10
print(c or b) --1
print(not nil)--true
print(not 0)--false
x=19
y=10
z=21
print((x>y) and x or y) --19 先and运算 后or
print((x>z) and x or z) --21
condition=10
if (condition>10) then
print("大于")
elseif (condition==10) then
print("等于")
else
print("xiao于")
end
语法
while(condition) do --当condition为true时执行
myfun()
end
a=10
while(a>0) do
io.write(a.." ")--10 9 8 7 6 5 4 3 2 1
a=a-1
end
语法
for var=exp1,exp2,exp3 do --var从exp1变化到exp2每次变化以exp3为步长默认exp3为1
myfun()
end
for i=1,10 do
io.write(i.." ")--1 2 3 4 5 6 7 8 9 10
end
语法
repeat
<执行块>
until(condition)
a=1
repeat
print(a.." ")--1 2 3
a=a+1
until(a>3)
使用#求数组长度是需要注意的是它只能用于序列(所有元素不为nil的列表)
--构建数组
array1={}
for i=1,10 do
array1[i]=i
end
for i=1,10 do
print(array1[i])-1 2 3 4 5 6 7 8 9 10
end
--求数组长度
print(#array1)-10
array1[5]=nil
print(#array1)--10
array1[20]=1
print(#array1)--10
array2={1,2,3,nil,nil}
print(#array2)--3
第一种方式创建矩阵
function createMetrax_1(M,N)
local mt={}
for i=1,M do
local row={}
mt[i]=row
for j=1,N do
row[j]=0
end
end
return mt
end
--第二中方式创建矩阵
function createMetrax_2(M,N)
local mt={}
for i=1,M do
local index=(i-1)*N
for j=1,N do
mt[index+j]=0
end
end
return mt
end
function printMetra(mt)
for i=1,#mt do
for j=1,#mt[1] do
io.write(mt[i][j]..',')
end
print()
end
end
mt1=createMetrax_1(5,2)
printMetra(mt1)
mt2=createMetrax_2(5,3)
print(#mt2)--15
lis={next=nil,value=nil}--创建链表
function createLink(list)
head=list
repeat
x=io.read()
list1={next=nil,value=x}
head.next=list1
head=head.next
until(x=='a')
end
function InsertData(lits,i,n)--在第i个插入n
local t=1
local head=lits
while(t<i) do
head=head.next
t=t+1
end
temp={next=head.next,value=n}
head.next=temp
end
function printLink(link)
l=link.next
while l do
io.write(l.value..",")
l=l.next
end
print()
end
createLink(lis)
printLink(lis)--1,2,3,4,a
InsertData(lis,3,22)
printLink(lis)--1,2,22,3,4,a
stack1={bottom=1,top=0}--创建栈
function push(stack,n)--入栈
stack.top=stack.top+1
stack[stack.top]=n
end
function pop(stack)--出栈 未进行安全判断
local value=stack[stack.top]
stack.top=stack.top-1
return value
end
push(stack1,1)
push(stack1,2)
for i=1,stack1.top do
io.write(stack1[i]..",")
end
print()
pop(stack1)
for i=1,stack1.top do
io.write(stack1[i]..",")
end
模块就是一些可以被require加载的代码,创建和返回一个表。然后根据表调用里面的内容。使用require加载的代码相当于引用命名空间。
--Lua1.lua
re=require "module" --这里的re相当于模块中的module表
print(re.val)
re.func_1()
--re.func_2()--不能直接调用模块中的局部方法
re.func_3()
--module.lua
module={}
module.func_1=function()
print("调用模块中的 func_1方法")
end
module.val=10
local function func_2()
print("调用模块中的局部函数")
end
function module.func_3()
print("调用模块中的func_3")
func_2()
end
return module
定义:元表是一个普通的lua表,定义了原始值的某些特殊操作下的行为。可以通过在其元表中设置特定字段来更改对值的操作行为。
例如:当一个非数字值进行加法操作数时,Lua会检查其元表中的“__add”字段中的函数,通过调用这个函数执行加法
--设置元表
mytable={}--普通表
mymetatable={}--元表
setmetatable(mytable,mymetatable)--把mymetatable设为mytable的元表
元方法是指元表事件中的键和值如上述加法中事件是“add”,元方法是执行加法的函数。
--实现两个表数据的相加
--对mytable设置元表
mytable=setmetatable({10,12,13},{__add=function(mytable,table2)
local temp={}
for i=1,#mytable do
if i<=#table2 then
temp[i]=mytable[i]+table2[i]
end
end
if #mytable>#table2 then
for i=#table2+1,#mytable do
temp[i]=mytable[i]
end
elseif #mytable<#table2 then
for i=#mytable+1,#table2 do
temp[i]=table2[i]
end
end
return temp
end})
tabl={1,2,3,4}
temp=mytable+tabl
for i=1,#temp do
print(temp[i])--11 14 16 4
end
mytable=setmetatable({"st",key_1="value_1"},{__index={key="value",le="asd",
func_1=function()
print("调用func_1方法")
end}})
print(mytable.key_1)--value_1
print(mytable.key)--value
mytable.func_1()--调用func_1方法
mymetatable={}--元表
mytable=setmetatable({key1="value1"},{__newindex=mymetatable})--进行设置元表
print(mytable.key1)
mytable.newkey="newvalue"
print(mytable.newkey,mymetatable.newkey)--nil newvalue
mytable.key1="value_1"
print(mytable.key1,mymetatable.key1)--value_1 nil
--修改版本1.0 添加__index元表使原表可以访问存储在元表中的值
mymetatable={}--元表
mytable=setmetatable({key1="value1"},{__index=mymetatable,__newindex=mymetatable})--进行设置元表
print(mytable.key1)
mytable.newkey="newvalue"
print(mytable.newkey,mymetatable.newkey)--newvalue newvalue
mytable.key1="value_1"
print(mytable.key1,mymetatable.key1)--value_1 nil
--通过rawset(t,k,v)函数进行更新表可以绕过元方法
mytable=setmetatable({key1="value1"},{__newindex=function(mytable,key,value)
rawset(mytable,key,value)
end})
mytable.key2="value2"
mytable.key1="new value"
print(mytable.key1,mytable.key2)--new value value2
function readOnly(t)
local agent={}--代理表
local mt={
__index=t,
__newindex=function(t,k,v)
error("this is a only read table")
end
}
setmetatable(agent,mt)--为代理表设置
return agent
end
test=readOnly({"red","or","blue"})
print(test[1])--red
test[2]="white"--lua: LuaStudy_1.lua:140: this is a only read table
--主要是agent表中并没数据,数据存储在元表中
--对其进行赋值时不管是否存在键值都会调用其元表中的__newindex方法
mytable=setmetatable({key1="this",key2="is",key3="a",key4="joke!"},
{__tostring=function(mytable)
local temp=''
for k,v in pairs(mytable) do
temp=temp..v.." "
end
return temp
end})
print(mytable)--this a joke! is
关于为什么没按照键值输出 主要是lua中数组(表)也没有顺序
--顺序遍历表
--主要方法是将表中的键进行排序 pair遍历表时键会随机的顺序出现
function pairsSort(t)
local a={}
for k in pairs(t) do
a[#a+1]=k
end
table.sort(a)
local i=0
return function()--这里涉及闭包概念。。。
i=i+1
return a[i],t[a[i]]
end
end
mytable={key1="this",key2="is",key3="a",key4="joke!"}
for k,v in pairsSort(mytable) do
print(v) -- this is a joke!
end
lua中的对象是由table+function组成
面向对象的特征封装、继承、多态、抽象
首先看一个简单的类的例子
Algorithm={result=0}--元类
--基础基方法 相当于其他语言中new方法
function Algorithm:new(o)--使用: 隐藏self参数
o=o or {} --o相当于对象中的原表
setmetatable(o,self)--设置元表 self是指对象
self.__index=self--self 相当于其他语言中的this 将对象本身添加到__index元方法中
return o
end
--基础类方法
function Algorithm:printResult(x,y)--运算方法
print(self.result)
end
function Algorithm:test()
print(self.key1)
end
myal=Algorithm:new(nil)--创建对象
myal:printResult(1,2)--0
myval=Algorithm:new({key1="value1",key2="value2"})
print(myval.key1)--value1
myval:test()--value1
加法类
AddAlgorithm=Algorithm:new()
function AddAlgorithm:new(o)
o=o or Algorithm:new()
setmetatable(o,self)
self.__index=self
return o
end
--重写
function AddAlgorithm:printResult(x,y)
self.result=x+y
print(x.."+"..y.."="..self.result)
end
--减法类
SubAlgorithm=Algorithm:new()
function SubAlgorithm:new(o)
o=o or Algorithm:new()
setmetatable(o,self)
self.__index=self
return o
end
function SubAlgorithm:printResult(x,y)
self.result=x-y
print(x.."-"..y.."="..self.result)
end
--乘法类
MulAlgorithm=Algorithm:new()
function MulAlgorithm:new(o)
o=o or Algorithm:new()
setmetatable(o,self)
self.__index=self
return o
end
function MulAlgorithm:printResult(x,y)
self.result=x*y
print(x.."*"..y.."="..self.result)
end
addt=AddAlgorithm:new(nil)
subt=SubAlgorithm:new(nil)
mult=MulAlgorithm:new(nil)
addt:printResult(1,2)--1+2=3
subt:printResult(1,2)--1-2=-1
mult:printResult(1,2)--1*2=2
mult:test()--调用父类中的test()
function GetSet(value)
return function(action,v)
if action=="get" then return value
elseif action=="set" then value=v
end
end
end
test=GetSet(0)--此时test就是function(action,v)对象
print(test("get"))--0
test("set",10)
print(d("get"))--10
--这里的self表以及subData都是私有的外界不可访问
function Algorithm(data)
local self={balance=data}
local addData=function(v)
self.balance=self.balance+v
end
local subData=function(v)
self.balance=self.balance-v
end
local getBalance=function()
return self.balance
end
return {addData=addData,getBalance=getBalance}
end
test=Algorithm(10)
test.addData(10)
print(test.getBalance())--20
Lua 中的协程代表一个独立的执行线程
线程与协程的主要区別在于,一个多线程程序可以并行运行多个线程,而协程在任意指定的时刻只能有一个协程运行。
方法 | 描述 |
---|---|
coroutine.create(f) | 创建一个协程 其中f必须是一个函数。并返回一个类型为线程的对象 |
coroutine.resume(co[,val1,…]) | 开始或继续执行协程 co |
coroutine.status(co) | 以字符串形式返回协程 co 的状态挂起(suspended),运行(running),正常(normal),死亡(dead) |
coroutine.wrap(f) | 创建一个新的协程,主体为 f。 f 必须是一个函数。返回一个函数,该函数在每次调用时恢复协程 |
coroutine.yield(…) | 暂停调用协程的执行 |
还有个coroutine.yieldable()官方解释Returns true when the running coroutine can yield. | |
和coroutine.running()返回正在运行的协程 不知道如何用【TODO】 |
--当协程处于yield状态时需要重新唤醒协程
第一种创建协程方法
co=coroutine.create(function(x,y)
coroutine.yield(x,y)
print("yield..")
return x,y
end)
print(coroutine.status(co))--suspended挂起状态
print(coroutine.resume(co,1,2))--true 1 2
print(coroutine.status(co))--suspended
xx,a,b=coroutine.resume(co)--yield..
print(xx,a,b)--true 1 2
第二种创建协程的方法 使用wrap创建协程时不需要resume启动
cp=coroutine.wrap(function()
print("cp")
coroutine.yield()
print("cp1")
end)
print(type(cp))--function
cp()--cp
cp()--cp1
print(math.ceil(2.1))--3
print(math.floor(2.1)) --2
print(math.cos(1.0/3*math.pi)) --0.5
print(math.deg(1.0/6*math.pi))--30
print(math.modf(10.0)) --10 0
print(math.modf(10.1)) --10 0.1
print(math.random())--返回一个[0,1]之间的浮点数
print(math.random(2,4))--返回一个[2,4]之间的整数
print(math.random(10))--返回1-10之间的整数
math.tointeger(10.1)-- nil
math.tointeger(10)--10
math.tointeger('')--nil
math.type(10.1)--float
math.type(10)--integer
math.type('')--nil
以上内容参考–Lua程序设计第4版–菜鸟教程Lua–Lua5.3 Reference Manual