语言执行方式
编译型语言:代码在运行前需要使用编译器,先将程序源代码编译为可执行文件,再执行。
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)