Lua基础

语言执行方式

编译型语言:代码在运行前需要使用编译器,先将程序源代码编译为可执行文件,再执行。
			C/C++
			Java,C#
			Go,Objective-C
			
解释型语言(脚本语言):需要提前安装编程语言解析器,运行时使用解析器执行代码
			JavaScript(TypeScript)
			Python,PHP,Perl,Ruby
			SQL
			Lua
			特点:运行才能调试,运行速度稍慢,开发速度快。


Lua是什么

Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的
是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。


Lua特点

轻量级: 它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的
嵌入别的程序里。
可扩展: Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供
一部分功能,Lua可以使用它们,就像是本来就内置的功能一样。



使用方式

需要高性能的程序部分,使用(C/C++)实现。需要快速实现功能部分,使用Lua实现。


国内游戏行业流行的Lua使用方式

Cocos2D-X(Cocos):核心引擎使用C++实现,提供LuaBinding(API的Lua调用),
游戏逻辑开发部分可使用Lua开发(刀塔传奇)
Unity3D:使用如xLua插件(API的Lua调用),实现游戏核心代码使用C#实现
(打包时il2cpp,编译为C++),游戏逻辑使用Lua开发(王者荣耀)

--//c#的单横注释
--lua的单横注释

--[[
/*
c#的多横注释
*/
]]

--[[
lua的多行注释
]]
--c#定义变量
--类型 变量名 =变量值
--string name="liuhongze";
--Lua会自动推导变量类型
--Lua可以写分号,也可以不写分号
name="liuhongze"
--调用变量
--c#Debug.Log()  console.writeline()
print(name)

--内置变量
--特点:下划线加大写字母
--查看Lua版本 
print(_VERSION)
--可以调用一个不存在的变量
--值是nil,等同于c#里面的空
print(id)

--销毁一个已经定义的变量
 name=nil
 print(name)

 --全局变量和局部变量
 --data="liuhongze"  定义了一个全局变量
 --一般开发中轻易不会使用全局变量,因为全局变量可以被随意的修改,不安全,不稳定
 local data="liuhongze"--定义了一个局部变量(data的作用域是当前文件)
 print(data)
local name = "Unity"
--获得变量的类型 使用type()
--type()是函数结构,是一个代码片段,可以重复调用执行,有参数有返回值
print(type(name))

--获得tpye返回值的类型
--type()返回值的类型是string
print(type(type(name)))

--对一个没有定义的变量获取类型
print(type(bb))

--判断一个未定义的变量
print(type(bb)=="nil")

--数字类型的数值
--c#常见 的数字类型,被归到number数据类型下
print(type(123))

--布尔类型的数值
--布尔有true和false
print(type(true))

--单引号字符串
print(type('123'))

--Lua的表
--数组初始化
--c# string[] data=new string[20];

local data = {}


--起始索引是1开始
--类型可以混合
--索引值可以为负数
--即使索引从1开始,也可以赋值0索引
--索引可以断开
--初始化时,对于没有索引的值,索引是从1向上累加的
--初始化提供索引赋值方法,[索引号]=数值
data={"asd",123,[-1]=100,"asds",[4]=99,[5]=233}

print(data[1])
print(data[2])
print(data[3])
print(data[4])

--获取数组的长度
--这种方式,获得的是从1索引开始,索引连续的数据个数,中间断开,计数结束
--这种方式不稳定
print(#data)

--修改某一个值
data[1]="def"
print(data[1])

--多维数组
local data2 = {{"aa","bb"},{11,22}}
print(data2[2][1])

--数组在Lua中是用Table实现的
--2的3次方
print(2^3)

--c#中不等于"!="
--Lua"~="
print(2~=3)

--Lua没有++ --
local i = 0
i=i+1
i=i-1

--Lua没有+= -= *= /=
--[[
C#
	if(条件)
	{
		条件达成的语句块	
	}
]]

local con1 = true
if(con1)
then
	print("条件1达成")
end

--[[
c#
	if(条件)
	{
		条件达成的语句
	}
	else
	{
		否则达成的语句
	}
]]
if(con1)
	then
	print("条件1达成")
else
	print("else达成")
end

--[[
c#
	if(条件)
	{
		条件达成的语句块
	}
	else if()
	{
		elseif的条件
	}
	else
	{
		否则达成的语句块
	}
]]
if(false)
then
	print("条件1达成")
elseif(true)
then
	print("elseif的条件")
else
	print("else达成")
end

--[[
c#

if(条件)
{
	if(条件)
	{
		//进入第二层条件
	}
}
]]

if(con1)
then
	if(true)
	then
		print("进入第二层条件")
	end
end

--Lua没有switch,所以可以用if-elseif-else的结构代替

--[[
c#
while(条件)
{
	循环体
}
]]

local num = 1

while(num<3)--条件满足时,进入循环
do
	--local修饰的num 虽然是局部变量,但他的作用域是当前文件,
	--所以在循环体内可以取得值
	print(num)
	num=num+1
end
--[[
c# do while
do
{
	
}
while(条件)

至少执行一次do结构体内的代码,while条件满足时,再执行do代码
]]
local num = 1

repeat
	print(num)
	num=num+1
until(num>5)--直到条件满足时,跳出循环

-------------------------------------------

--[[
do
{
	if()
	{
		break;
	}
	if()
	{
		bresk;
	}
	if()
	{
		bresk;
	}
}
while(false)

//下面的代码
]]
--break会跳出循环,没有continue

--break     跳出当前循环体,
--continue 	跳出循环体中的当次循环,进入下一次循环
--return	终止程序向前,并可返回一个值
repeat
	if(false)
	then
		print("此处跳出1")
		break
	end
	if(true)
	then
		print("此处跳出2")
		break
	end
until(true)
local data = {"aa","bb","cc","dd","ee"}

--参数1.变量i的初始值,遍历Lua表使用1
--参数2.增长到多少
--参数3.增长步长,默认是1
for i=1,#data
do
	print(data[i])
end

--倒序遍历
for i=#data,1,-1
do
	print(data[i])
end
--第四个数往前遍历
for i=#data-1,1,-1
do
	print(data[i])
end



--迭代器(遍历table)
--one是不加中括号的字符串索引
--"aa" "bb" 自动加1,2索引
--[4]指定数字索引
--[-1]指定负数索引
--["two"]是加中括号的字符串索引
local  data = {one="cc","aa","bb",[4]=3,[-1]=4,["two"]="dd"}

--连续索引数值迭代器
--迭代器就是指向table的指针,连续数字索引迭代器只会获取从1开始的数字索引,
--且必须索引是连续的,才能持续获得值
--此处的for结构可以理解为C#的foreach结构
for k,v in ipairs(data)
do
print("k:"..k..",v:"..v)
end

print("--------------------------------")
--所有数值迭代器
--相对于ipairs,所有数值迭代器去掉了i,i可以理解为int,
--去掉了int的迭代器,也就去掉了连续数值的索引
--获取table长度的最稳定的方法,就是使用所有数值迭代器获取
for k,v in pairs(data)
do
print("k:"..k..",v:"..v)
end
--脚本型语言不能先调用,在定义,因为代码是从上往下执行的,
--c#可以是他在编译的过程中已经编译进去了

--第一种声明函数
function func1()
	print("这是func1")
end
--脚本型语言都是从上往下依次调用的,先定义,在调用
func1()



---------------------------
--将函数定义为一个变量,函数是一种数据类型
local  func2 = function()
	print("这是func2")
end
func2()



---------------------------
local  func3 = function(a,b)
	print(a+b)
end
--函数的调用,参数可以多于形参,但是不能少于形参
func3(5,7)
func3(7,8,9)



--------------------------------
local  func4 = function(...)
	--将无固定参数转化为table
	--arg的作用域是func4函数体
	local arg = {...}
	local total = 0
	for k,v in pairs(arg)
	do
		total=total+v
	end
	print(total)
end

func4(1,2,3)
func4(1,2,3,4,5)



---------------------------
local function func5()
	return 99,100
end
--将多返回值同时赋予两个变量
local num1,num2 = func5()
print(num1,num2)
--可以丢弃不要的
local _,n2 = func5()
print(n2)
--table支持数字索引存储数据
--Table支持字符串索引(关联索引)存储数据
local  data = {one="cc","aa","bb",[4]=3,[-1]=4,["two"]="dd"}

print(data[2])
print(data["one"])
print(data.two)
print(data.one)



--因为函数是一种数据类型
--所以将func1索引下定义了一个函数
data.func1=function()
	print("data表中的func1函数")
end
--所以data.func1调用数据,是个函数,也就调用了函数
data.func1()




----------------------------
data.func2=function()
	print("func2+"..data.two)
end
data.func2()



-------------------------------
--成员函数定义时,显式加入self变量,对应c#的this关键字
--函数内部可以通过self变量获取当前table的其他值或函数
data.func3=function(self)
	print("func3+"..self.two)
end
--调用时,必须使用":",因为":"调用,会对self关键字赋值
data:func3()




--------------------------------
--第二种self调用写法
--隐式给self赋值 
function data:func4()
	print("func4+"..self.two)
end
data:func4()
--实现代码的切分

--预加载目录
print(package.path)

print("----------------------------")

--将提供的lua文件中的代码执行一下
--文件名字不能包含比如"." 否则会加载错误
--文件扩展名.lua 不需要编写,因为会自动添加
require("01HelloWorld")

--表会记录已经加载的文件记录
print(package.loaded["01HelloWorld"])
--当每次加载文件时,都会检查package.loaded里面的内容,防止重复加载
--package.loaded里面存储的是加载的路径字符串
--如果想要重复多次加载一个文件,则需要再次加载前清除这个状态
package.loaded["01HelloWorld"]=nil

require("01HelloWorld")

--加载文件的相对路径
--"./"表示当前编写的Lua文件,所在的目录
--"../"表示当前编写的Lua文件,所在的上级目录
require("./01HelloWorld")

--获取另一个文件的局部变量
--子文件的return返回给主文件的变量
local config = require("./config")
print(config.appName)
--取到全局变量,但是不安全,很容易被覆盖
print(APPNAME)


-------------------------./config
APPNAME="HXSD"
local config = {}
config.appName="hxsd"

return config
-------------------------------------元表tostring-------------
local t1 = {1,2,3}
local t2 = {4,5,6}

--直接打印表,显示的是内存地址
--期望打印table时,以人类易于阅读的结构显示"{1,2,3}",方便调试

--打印时,将表作为字符串输出
--实现的功能,当需要将表作为字符串使用时,应该有一种办法
--这种办法,Lua提供了这种语法特性,metatable扩展,元表扩展
print(t1)

setmetatable(
	t1,--需要进行元表扩展的数据表
	{  	--用于扩展t1的元表,只要在元表中实现一些特殊的函数,
		--则t1就可以实现一些特殊的功能,比如让t1作为字符串可以使用

		__tostring=function(t) --原方法,当被扩展的表被以string方式调用时,调用
			local format = "{"
			for k,v in pairs(t)
				do
				format=format..v..','
			end
			format=format.."}"
			return format
		end
	}
)

--t1会被传递给t
print(t1)
print("----------------封装起来-------------------")
local mate = 
{  	
		__tostring=function(t) 
			local format = "{"
			for k,v in pairs(t)
				do
				format=format..v..','
			end
			format=format.."}"
			return format
		end
}
setmetatable(t1,mate)
setmetatable(t2,mate)
print(t1)
print(t2)
--------------获得不规则Table的准确长度
local  data = {one="cc","aa","bb",[4]=3,[-1]=4,["two"]="dd"}
count=0
for k,v in pairs(data)
do
count=count+1
end
print(count)
print("--------------------------------------------------------")
-------------------方法二,工具类

local  data = {one="cc","aa","bb",[4]=3,[-1]=4,["two"]="dd"}
--工具类
local TOOL = {}
function TOOL: tablecount(t)
local count=0
for k,v in pairs(data)
do
count=count+1
end
return count
end

print(TOOL:tablecount(data))






---------------------------------------------Lua for冒泡循环
local  func4 = function(...)
	local arg = {...}
	for i=1,#arg
	do
		for j=1,#arg-i
		do
			if(arg[j]>arg[j+1])
			then
			num=arg[j]
			arg[j]= arg[j+1]
			arg[j+1]=num
			end
		end
	end

	for k,v in pairs(arg)
	do
	print("k:"..k..",v:"..v)
	end
end
func4(66,85,78,5,55)





--------------------------------------------------------------------------------
--使用元表的__add元方法,实现两个Table的所有元素的合并
mytable = setmetatable({ 1, 2, 3 },
{
  	__add = function(mytable, newtable)
    for i = 1, #mytable 
    do
    	table.insert(mytable, #mytable+1,newtable[i])
    end
    return mytable
  end
})

secondtable = {4,5,6}
mytable = mytable + secondtable

for k,v in ipairs(mytable) 
do
print(k,v)
end



-------------------方法二



local t1 = {4,5,6}
local t2 = {7,8,9}

local meta = 
{
	__add=function ( t1,t2 )
	local new_t = {}
	for k,v in pairs(t1)
	do
		--插入
		table.insert(new_t,v)
	end
	for k,v in pairs(t2)
	do
		table.insert(new_t,v)
	end
	return new_t
	end, 


	__tostring=function(t) 
	local format = "{"
		for k,v in pairs(t)
		do
			format=format..v..','
		end
		format=format.."}"
		return format
	end
}
setmetatable (t1,meta)
local t3 = t1+t2
setmetatable (t3,meta)
print(t3)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值