lua基本语法

在此前,仅仅是了解tolua的客户端实现热更新的一个框架代码,对于lua由于用的较少,日子久了反而忘记的很快,在此记录下笔记,对于lua的基本语法总结于此。

lua的运行环境

安装LuaForWindows_v5.1.4-39

lua的文件格式:xxx.lua

注:文件不可直接运行,也不需要像c++那般进行编译,运行环境内部存在一个luac.exe的程序(执行lua代码);程序没有入口函数,在文件中从上往下依次执行

Lua特点

可扩展性很强,在游戏领域lua主要用于做界面的开发,可与c++/c#这些大型语言进行结合;

简单,小巧,无法用于开发大型的功能,基于一门大型主语言进行开发;

高效率;

与平台无关。

概念

Chunks

chunk是lua执行的一个语句,也可以是每一块语句(即一系列语句的组合),还可以是函数。

注:lua当中每个语句结尾的分号(;)是可选的,但是如果在同一行存在多个语句最好是用;分开

全局变量

lua当中全局变量不需要声明(局部变量也是如此),给一个变量赋值后即创建了这个全局变量,访问一个没有初始化的全局变量野不会出错,只不过得到的结果是:nil。

g_value =10
print(g_alue) --假若变量敲错了 lua并不会报错
print(g_value)
g_value = nil  --如果你想删除一个全局变量,只需要将变量负值为nil
               --即当且仅当一个变量不等于nil时,这个变量存在
print(g_value)
--输出结果为:
--nil
--10
--nil

注:lua是对大小写敏感;

注释符

单行注释符:--

多行注释符:--[[      --]]

--[[
vas = 20; --定义一个全局变量
print(g_vas);
--]]

基本数据类型

lua当中变量不需要类型定义;存在8个基本类型:nil、boolean、number、string、userdata、function、thread、table。

nil:Lua中特殊的类型,他只有一个值:nil;一个全局变量没有被赋值以前默认值为nil;给全局变量负nil可以删除该变量。

boolean:存在两个取值false和true。但要注意Lua中所有的值都可以作为条件。在控制结构的条件中除了false和nil为假,其他值都为真。所以Lua认为0和空串都是真。

number:表示实数,Lua中没有整数。Lua的numbers可以处理任何长整数不用担心误差。

string:指字符的序列。lua是8位字节,所以字符串可以包含任何数值字符,Lua中字符串是不可以修改的,并且string和其他对象一样,Lua自动进行内存分配和释放,可以使用单引号或者双引号表示字符串

function:表示函数,可以存储在变量中,可以作为函数的参数,也可以作为函数的返回值

函数type:测试给定变量或者值的类型

print:打印输出的函数

print(type("Hello world"))      --> string
print(type(10.4*3))             --> number
print(type(print))              --> function
print(type(type))               --> function
print(type(true))               --> boolean
print(type(nil))                --> nil
print(type(type(X)))            --> string

算术运算符

二元运算符:+ - * / ^  (加减乘除幂)

一元运算符:-  (负值)

注:这些运算符的操作数都是实数。

print(1+2) -- 3
print(1-2) -- -1
print(1*2) -- 2
print(1/2) -- 0.5
print(2^2) -- 4

关系运算符

存在以下几种运算符:<      >      <=     >=     ==     ~=

注:

  • 操作符返回结果为false或者true;==和~=比较两个值,如果两个值类型不同,Lua认为两者不同;nil只和自己相等;
  • Lua通过引用比较tables、userdata、functions。也就是说当且仅当两者表示同一个对象时相等;
  • Lua比较数字按传统的数字大小进行,比较字符串按字母的顺序进行,类似于strcmp;
  • 混合比较数字和字符串,Lua会报错,比如:2 < "15"。
print(1>2) --false
print(1>=2) --false
print(1<2) --true
print(1<=2) --true
print(1==2) --false
print(1~=2) --true
print(1 == type(1)) --false

逻辑运算符

存在以下几种运算符:and    or     not

注:

  • 逻辑运算符认为false和nil是假(false),其他为真,0也是true.
  • and和or的运算结果不是true和false,而是和它的两个操作数相关。
print(1<2 and 1>2) --false
print(1<2 or 1>2) --true
print(not(1<2)) --false
print(not nil) --true
print(not 0) --false
a=4
b=5
print(a and b)           -- 5   如果a为false,则返回a,否则返回b
print(a or b)            -- 4
print(nil and 13)        -- nil
print(false and 13)      -- false
print(false or b)        -- 5   如果a为true,则返回a,否则返回b
-- 一个很实用的技巧:如果x为false或者nil则给x赋初始值v
x = x or a
--等价于
if not x then
    x = a
end
--打印a的值
print(x); --4

连接运算符

符号:..

注:字符串连接,如果操作数为数字,Lua将数字转成字符串。

print("Hello " .. "World")      --> Hello World
value = 100
print(value .. 'rmb')                   --> 100rmb

优先级

从高到低的顺序:

^
not    - (unary)
*      /
+      -
..
<      >      <=     >=     ~=     ==
and
or

注:除了^和..外所有的二元运算符都是左连接的。

表(table)

表是Lua特有的功能强大的东西。最简单的构造函数是{},用来创建一个空表;构造函数可以使用任何表达式初始化;不管用何种方式创建table,我们都可以向表中添加或者删除任何类型的域,构造函数仅仅影响表的初始化。

两次形式:

数组型:

注:

  • 第一个元素索引为1,即下表从1开始;
  • 越界返回nil,程序不会崩溃;
days = {"Sunday", "Monday", "Tuesday", "Wednesday","Thursday", "Friday", "Saturday"}
print(days[4])       -- Wednesday
print(days[9])       -- nil

record型:

a = {x=3, y=4}
--可写成
--[[
a = 
{
	x=3, 
	y=4
}
--]]
--等价于    a = {}; a.x=0; a.y=0 
print(a.x) --3 类似于结构体的方式访问元素
print(a.y) --4
print(a['x']) --3 --类似于map键值对的方式访问元素
--向表中添加或者删除任何类型的域
w = {x=0, y=0, label="console"}
x = {1, 2, 3}
w[1] = "hello word"
x.f = w  --向x表中添加成员f,f即是表w
print(w["x"])     --> 0
print(w[1])       --> hello word
print(x.f[1])     --> hello word
w.x = nil         -- remove "x"

在同一个构造函数中可以混合列表风格和record风格进行初始化:

polyline = {color="blue", thickness=2, npoints=4,
				{x=0,   y=0},
				{x=-10, y=0},
				{x=-10, y=1},
				{x=0,   y=1}
}
print(polyline[1].x)     -- 0
print(polyline[2].x)     -- -10

opnames = {["+"] = "add", ["-"] = "sub",["*"] = "mul", ["/"] = "div"}
i = 20; s = "-"
a = {[i+0] = s, [i+1] = s..s, [i+2] = s..s..s}
print(opnames[s])    --> sub
print(a[22])         --> ---

实现数组型表的下表从0开始(不推荐数组下标从0开始,否则很多标准库不能使用)

days = {[0]="Sunday", "Monday", "Tuesday", "Wednesday","Thursday", "Friday", "Saturday"}
print(days[0])         --> Sunday

在构造函数的最后的","是可选的,可以方便以后的扩展;在构造函数中域分隔符逗号(",")可以用分号(";")替代,通常我们使用分号用来分割不同类型的表元素。

t = {a=10, b=45; "one", "two", "three",}

赋值语句

赋值是改变一个变量的值和改变表域的最基本的方法,Lua可以对多个变量同时赋值,变量列表和值列表的各个元素用逗号分开,赋值语句右边的值会依次赋给左边的变量。

注:多值赋值经常用来交换变量,或将函数调用返回给变量。

value1, value2 = 10, 2*10       --       value1=10; value2=20
print('value1 = ' .. value1);
print('value2 = ' .. value2);
--遇到赋值语句Lua会先计算右边所有的值然后再执行赋值操作
--所以我们可以这样进行交换变量的值:
value1,value2 = value2,value1
print('value1 = ' .. value1);
print('value2 = ' .. value2);

当变量个数和值的个数不一致时,Lua会一直以变量个数为基础采取以下策略:

  • 变量个数 > 值的个数,则按变量个数补足nil
  •  变量个数 < 值的个数,则多余的值会被忽略
a, b, c = 0, 1 
print(a,b,c)             --> 0   1   nil

局部变量与代码块

使用local创建一个局部变量,与全局变量不同,局部变量只在被声明的那个代码块内有效。代码块:指一个控制结构内(if-else等等),一个函数体,或者一个chunk(变量被声明的那个文件或者文本串)。

value = 1
if true then
	local value = 2;
	print('local:value = ' .. value) --2
end
	print('grobal:value = ' .. value) --1

控制结构语句

涵盖if-else语句、while语句、repeat-until语句、for循环

注:控制结构的条件表达式结果可以是任何值,Lua认为false和nil为假,其他值为真。

if-else语句:

格式:

if conditions then 
    then-part
end;

if conditions then 
    then-part
else
    else-part
end;

if conditions then 
    then-part
elseif conditions then
    elseif-part
..            --->多个elseif
else
    else-part
end;

while语句:

格式:

while condition do
    statements;
end;

repeat-until语句:

格式:

repeat
    statements;
until conditions;

示例代码:

--if-else
state = 5
if state < 4 then
	print('state:'.. state .. '<4')
elseif state>=4 and state<10 then
	print('state:'.. state .. '>=4 and state <10')
else
	print('i>=10')
end
---while
local i =0
while i < 10 do
	i=i+1
	print(i)
end
--repeat-until
local j = 0
repeat
	j = j+1
	print(j)
until j >= 10

for循环:

数值for循环:

for将用exp3作为step(步长)从exp1(初始值)到exp2(终止值),执行loop-part。其中exp3可以省略,默认step=1

注: 

  • 三个表达式只会被计算一次,并且是在循环开始前;
  • 控制变量var是局部变量自动被声明,并且只在循环内有效;
  • 如果需要保留控制变量的值,需要在循环中将其保存;
  • 循环过程中不要改变控制变量的值,那样做的结果是不可预知的。如果要退出循环,使用break语句。
  • Lua当中不存在continue语句,存在break和return

格式:

for var=exp1,exp2,exp3 do
    loop-part
end

代码示例:

for i =1,10,2 do
	print(i) --13579
end
for i =1,10 do
	print(i) --123456789
end

范型for循环:

--如果遍历数组型表,key为整型则ipairs和pairs都可使用,否则只能用pairs
t1= {10,20,30,40,50,60}
for key,value in ipairs(t1) do 
	print(key..','..value) --1,10 2,20 3,30 4,40 5,50 6,60
end
for key,value in pairs(t1) do 
	print(key..','..value) --1,10 2,20 3,30 4,40 5,50 6,60
end

t2= {x=11,y=21,z=31}
for key,value in pairs(t2) do 
	print(key..','..value) --y,21 x,11 z,31
end

函数

函数有两种用途:

  • 完成指定的任务,这种情况下函数作为调用语句使用;
  • 计算并返回值,这种情况下函数作为赋值语句的表达式使用。

格式:

function func_name (arguments-list)
    statements-list;
end;

示例代码:

function funtmp1(a,b)
	if a > b then
		print('a > b')
		return a-b
	else
		print('a < b')
		return b-a
	end
end
local res = funtmp1(100,200)
print(res)  --a<b 100
function funtmp2(a,b)
	return a+b,a-b,a*b,a/b
end
--多值赋值经常用来交换变量,或将函数调用返回给变量
local ret1,ret2,ret3 = funtmp2(100,200)
print(ret1..','..ret2..','..ret3) --300,-100,20000
local ret11,ret22,ret33,ret44 = funtmp2(100,200)
print(ret11..','..ret22..','..ret33..','..ret44) --300,-100,20000,0.5

Lua的面向对象

Lua中的表不仅在某种意义上是一种对象;两个不同值的对象(table)代表两个不同的对象;对象有他们的成员函数。

Account = {balance = 0}
--[[方法1
function Account.withdraw (v)
	Account.balance = Account.balance - v
	print(Account.balance) -- -100
end
Account.withdraw(100.00)
a = Account; Account = nil
a.withdraw(100.00)   -- ERROR!
--]]
--违背了前面的对象应该有独立的生命周期的原则
--定义方法的时候带上一个额外的参数,来表示方法作用的对象。这个参数经常为self或者this

--[[方法2
function Account.withdraw (self, v)
    self.balance = self.balance - v
	print(self.balance) -- -100
end
a1 = Account; Account = nil
print(a1.balance)   --0
a1.withdraw(a1, 100.00)     -- OK
--]]

--通过使用冒号操作符来隐藏这个参数的声明。我们可以重写上面的代码
--[[方法3
function Account:withdraw (v)
	self.balance = self.balance - v
	print(self.balance)  -- -100
end
a = Account; Account = nil
a:withdraw(100.00) 
--]]
--两种用法的使用总结
Account = {
	balance=0,
	withdraw = function (self, v)
		self.balance = self.balance - v
		print(self.balance) --200
	end
}

function Account:deposit (v)
	self.balance = self.balance + v
	print(self.balance) --100
end
Account.deposit(Account, 200.00)
Account:withdraw(100.00)

参考文献:lua程序设计

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值