Lua编程(初级入门)

1.什么是lua语言

轻量的脚本语言,使用标准c语言的源代码形式开发,目的为了嵌入应用程序中,为应用程序提供灵活的拓展和定制功能

2.lua与C#区别

几乎所有平台os都可以编译运行,可以很方便的更新代码。

C#只能在特定的操作系统中编译成dll文件,然后打包进安装包运行,在移动平台上不能更新替换已有的dll文件,除非重新下载

3.Lua的第一行代码

下载Lua安装之后有两个可运行的程序

一个是Lua,输入Lua的代码直接可以运行。

还有一个时SciTE的一个Lua的IDE,SciTE要先保存到本地(保存的文件要加.lua后缀),才能进行编译运行。

4.print方法、单行和多行注释

--单行注释

--[[
多行注释
--]]

5.Lua中的标识符命名规则

标示符以一个字母A到Z或a到z或下划线开头

Lua是一个区分大小写的编程语言

6.全局变量

在默认情况下,变量总是认为时全局的

全局变量不需要声明,给一个值赋值后,及创建了这个全局变量

 一个变量没有赋值的时候,它是nil

7.Lua数据类型

nil一个空的

boolean包括false and true

number包含小数和整数

string字符串由一对双引号或者单引号来表示

function由c或Lua编写的函数

userdata表示任意存储在变量中的C数据结构

thread表示执行的独立线路,用于执行协同程序

table表类型,其实是一个关联数组

print(type("Hello world"))
print(type(1.66))
print(type(print))
Lua中type方法返回一个string的值,表示参数的类型,上面打印的值

string
number
function

8.nil的用法

任何一个没有定义的值,都会是nil

通过将nil赋值给某个变量,可以置空变量的值,让变量的值从内存释放

9.boolean布尔

如果把nil当作boolean类型,会被视为false

if true then
print("true")
end

if nil then
print("nil is true")
else
print("nil is false")
end

输出

true
nil is false

10.number数字类型的用法

既可以表示整数也可以表示小数

11.string字符串类型的用法

字符串组拼

print("2".."2")

多行字符串

html =
[[
<html>
<head></head>
<body>
<a href = "baidu">ok</a>
</body>
</html>

]]

运算字符串变量的长度

print(#html)

12.table表的用法

表的使用

tab1 = {}
tab2 = {key = 100,key2 = "value2"}--初始化一个表
print(tab1)
print(tab2.key2)
print(tab2["key"])

输出结果

table: 00A59270
value2
100

直接输出得到的是table的内存地址,表中的值有两种调用方式用点或者中括号,中括号中间要加双引号

  在Lua中数组是从1开始的

tab3 ={"test001","test200"}

print(tab3[1])
print(tab3["2"])

输出结果

test001
nil

两种索引的结果不一样加上双引号,就会索引双引号之中的key的value

循环遍历

for key,val in pairs(tab3) do
print(key..":"..val)
end

pairs是一个方法,将tab3中的键和值分别赋值给key和val,直到tab3中没有值为止

table表中修改

通过点或者中括号来添加新的值给table

将键值对中的值设置为nil,就相当于直接删除了这个键值对

在table中索引是不连续的,如果删除了一个,后面的值不会向前移动

13.function函数的用法

阶乘的Lua实现

在创建方法的时候,不用定义返回值和参数类型,参数在调用的时候决定类型,返回值也是在调用的时候直接返回

function fact(n)
	if n ==1 then
	return n;
	else
	return n*fact(n-1)
	end
end

print(fact(3))

function函数作为参数传递和匿名函数的用法

将定义的函数作为参数进行传递

function testFun(tab,fun)
	for k,v in pairs(tab) do
		fun(k,v)
	end
end
tab = {key1 = "val1",key2 = "val2"}

function	f1(k,v)
	print(k..":"..v)
end

testFun(tab,f1)

匿名函数

只能使用一次,在其他地方无法调用这个函数。一般情况下匿名函数代码比较短

testFun(tab,function(k,v) print(k.."  "..v)end)

14.字符串常见操作

字符串的替换和查找


str = "sss.baid.com"
str4 = string.gsub(str,"s","w")

print(str,str4)

str5 = string.find(str,"com")
print(str5)

打印结果

sss.baid.com    www.baid.com
10

字符串的组拼 %d代表数字类型,%s代表字符串类型

n1=1
n2=1
str6 = string.format("add:%d+%d = %d",n1,n2,(n1+n2))
print(str6)

打印结果

add:1+1 = 2

将byte转换成char型

mychar = string.char(98)
print(mychar)

将char型转换成byte型

将字符串中的第四个转换成byte类型

mybyte = string.byte("abcd",4)
print(mybyte)

求一个字符串的长度

length1 = string.len("abc")
print(length1)

返回一个字符串的n次拷贝

str = string.rep("abc",4)
print(str)

匹配正则表达式

string.gmatch(str,pattern)

每一次使用这个函数,返回一个在字符串str找到的下一个符合pattern描述的子串

15.Lua中数组的基本特性和定义

Lua中数组的遍历

array = {"Lua","C#"}

for i = 1,2 do
	print(array[i])
end

Lua中多维数组的实现

在一个表中再创建一个的表,这样就是二维的数组了

array = {}
for i =1,3 do
	array[i] = {}
	for j =1,2 do
		array[i][j] = i*j
		print(array[i][j])
	end
end

16.Lua中的迭代器函数

pairs就是一个迭代器,用来取得数组里的每一个数据

ipairs按照索引从1开始,递增遍历,遇到nil值就停止

自定义迭代函数

不断迭代直到control达到state的值

function square(state,control)
	if(control>=state) then
		return nil
	else
		control = control + 1
		return control,control*control
	end
end

for i,j in square,9,0 do
	print(i,j)
end

17.Lua中的表

Lua中的表如果有两个引用

一个置为空,另一个表还在引用,那么这个表就不会被释放,直到两个引用都置为空,这个表才会被置为空

表中的元素可以使用table.concat()方法进行拼接,方法返回值是一个字符串

insert方法在table插入新的值

mytable = {"Lua","c#"}
table.insert(mytable,"java")

print(table.concat(mytable," "))

使用table中的remove方法移除指定位置的table的元素,insert在插入的时候出传入一个值,就会在指定的位置插入元素

table.insert(mytable,1,"python")
table.remove(mytable,3)

表的排序

使用table中的sort方法对table中的元素进行排序,如果是字符,会根据ASCII码进行排序

18.Lua中的模块和包

定义一个module

mytable = {"Lua","c#"}

mytable.func1 = function()
	print("this is module func")
end

return mytable
--引用模块
require "01"

mytable.func1()

C包

C包指用C语言写的C包,一些c语言写成的拓展的包

19.Lua中的元表(Metatable)

在普通表中拓展出来的,元表用来定义一些非常规的操作,是对普通表进行行为的扩展

mytable = {"Lua","java"}

mymetatable = {}--元表

mytable = setmetatable(mytable,mymetatable)--设置元表,返回普通表

print(getmetatable(mytable))--得到普通表对应的元表

使用setmetatable方法将元表和普通表关联

使用getmetatable方法得到元表

元表中的__index键,设置了__index,在表中调用不存在的元素的时候,就会调用__index指定的相应方法

mymetatable = {
__index = function(tab,key)
	print("index func")
end
}--元表

mytable = setmetatable(mytable,mymetatable)--设置元表,返回普通表

print(mytable[10])

输出结果

index func
nil

__index用来处理访问到的索引不存在的时候,怎么办,不仅可以指向一个函数,也可以指向一个表。

__newindex在我们给表添加新的键值对的时候调用

mytable = {"Lua","java"}

mymetatable = {
__newindex = function(tab,key,value)
	print("key"..key..": get value "..value)
end
}--元表

mytable = setmetatable(mytable,mymetatable)--设置元表,返回普通表

mytable[5] = "python"

输出结果:key5: get value python

__call键,在给表传入一个值的时候调用

mytable = {"Lua","java"}

mymetatable = {
__call = function(tab,arg)
	print(arg)
end
}--元表

mytable = setmetatable(mytable,mymetatable)--设置元表,返回普通表

mytable(34)

输出结果34

20.Lua协同程序

协程:有独立的堆栈、独立的局部变量、独立的指令指针

挂起一个函数也叫做暂停一个函数

定义和启动协同程序

 coroutine.create定义协同函数

coroutine.resume启动协同函数

--定义协同函数
co = coroutine.create(
	function (a,b)
		print(a+b)
	end
)
--启动协同函数
coroutine.resume(co,23,1)

第二种定义和启动方法

--定义协同函数
co = coroutine.wrap(
	function (a,b)
		print(a+b)
	end
)
--启动协同函数
co(23,1)

停止协同函数,继续执行主线程的情况。调用coroutine.yield()方法,挂起协同函数

--定义协同函数
co = coroutine.wrap(
	function (a,b)
		print(a+b)
		coroutine.yield()
		print(a-b)
	end
)
--启动协同函数
co(23,1)

print("test")

输出结果

23

test

再使用coroutine.resume()继续函数运行,但是不用再给函数传递参数

resume方法返回第一个值为是否启动了线程,第二个值是协同函数的返回值

--定义协同函数
co = coroutine.create(
	function (a,b)
		return a*b
	end
)
--启动协同函数
res1,res2 = coroutine.resume(co,23,1)

print(res1,res2)

输出结果:true    23

yield方法有多少个参数,都会传递出去

--定义协同函数
co = coroutine.create(
	function (a,b)
	coroutine.yield(a*b,a/b)
		return a+b
	end
)
--启动协同函数
res1,res2,res3 = coroutine.resume(co,20,2)

print(res1,res2,res3 )

res1,res2 = coroutine.resume(co,20,2)

print(res1,res2 )

输出结果:

true    40    10
true    22

协程程序和内部和外部(主程序)的数据传输

输出当前协程的状态

print(coroutine.status(co))

获取当前正在运行的线程

print(coroutine.running())

resume和yield配合可以再主程序和开的子线程中进行数据的传输

23.Lua中的简单模式下文件的I/O

文件读取

file = io.open("data.txt","r")
io.input(file)

print(io.read())--读取一行
print(io.read())

io.close(file)

文件写入

"w" 写入文件之前清空文件中的原有内容,写入文件新的内容

"a" 在原有的内容的后面,添加新的内容

24.完全模式下的文件读取和写入

通过file来进行文件的读取

file = io.open("data.txt","r")

print(file:read())

file:close()

25.Lua中的面向对象怎么实现

面向对象特征:封装、继承、多态、抽象

Lua中使用table+function来实现面向对象

--对于一个对象来说 属性、方法

person = {name = "RP"}
person.eat = function ()
	print(person.name.." is eating")
end

person.eat()

另一种定义方法的方法,这种方法可以在内部调用self来调用自己的属性

person = {name = "RP"}

function person:eat()
	print(self.name.." is eating")
end

person:eat()

当通过:调用的时候,系统过自动传递当前的table给self。

当通过. 调用方法的时候,self不会自动赋值,必须通过传递当前table给self

创建构造函数,用于构造拥有相同属性和函数的对象

通过new()方法来创建很多个相同的对象

person = {name = "RP"}

function person:new()
	local t = {}
	--调用一个属性的时候,如果t中不存在,那么会在__index所指定的table中查找
	setmetatable(t,{__index = self})
	return t
end

person1 = person:new()
person2 = person:new()
print(person1.name)
print(person1.name)

输出结果:

RP

RP

继承的实现

将new()方法创建的对象传递给student,student继承了person的属性、方法,stu继承student(也可以调用person的属性方法)

person = {name = "RP"}

function person:new()
	local t = {}
	--调用一个属性的时候,如果t中不存在,那么会在__index所指定的table中查找
	setmetatable(t,{__index = self})
	return t
end

student = person:new()
student.grade = 1

stu = student:new()

print(stu.grade)

猜你喜欢

转载自blog.csdn.net/Game_Builder/article/details/81383812