1. 变量命名规范
弱类型语言(动态类型语言),定义变量的时候,不需要类型修饰 而且,变量类型可以随时改变 每行代码结束的时候,要不要分号都可以 变量名 由数字,字母下划线组成,不能以数字开头,也不能是保留字,而且不可以使用特殊字符 变量名区分大小写,避免创建下划线开头加大写字母组成的变量名
2. 变量类型
变量分为三种类型,全局变量,局部变量,表字段 默认创建的都是全局变量,局部变量用 local 修饰
3. 保留字
4. 文档注释
-- [[
多行注释
]]
-- 单行注释
5. 基本数据类型
Lua 中有八种基本类型: nil、boolean、number、 string、function、userdata、 thread和table,库函数type返回一个描述给定值类型的字符串 type (v)返回其唯一参数的类型,编码为字符串
(1)nil ,在lua 中,只有false 和 nil 才表示假 0和空串表示真
(2)boolean 布尔类型
(3)string 字符串
str1="abcd";
str2=string.upper(str1);--转大写
print(str2);
print(string.lower(str2));--转小写
print(string.len(str1));--字符串长度
print(string.len("你好 lua"));--
print(string.reverse(str1));--反转
str3=789;
print("abc".."xyz"..str1..str2..123 ..456.56 ..str3..000);---连接符,number 如果在连接符左边,后面要空格
print("");
str4="abcd1234";
print(string.sub(str4,3,5));--截取,后面参数是开始位置和结束位置,结束位置可省略不写
print(string.sub(str4,-4,-2));--负数是从右往左数
--string.find(s, pattern, init, plain) 在字符串s中 查找pattern(可以是表达式),如果找到,则返回pattern 第一次出现的开始位置和结束位置,如果没找到,返回nil
str1="abcd1234";
--print(string.find(str1,"cd"));
--print(string.find(str1,"cd",3));--从指定位置处开始查找
--print(string.find(str1,"cd",-6));--如果是负数,则是从字符串长度+该负数的位置开始找
--print(string.find(str1,"%d",6));--最后一个参数,默认就是false,开启正则匹配模式
--print(string.find(str1,"(%d%d%d%d)"));
--print(string.find(str1,"%d",6,true));--最后一个参数,true 是直接当子串处理
(4)function
function 在lua 中一个基本的数据类型,是第一类值
格式
function funcName()
...
...
end
传参或返回值,都很自由
function 可以作为参数被传递,也可以作为值被赋值给另一个变量
(5)number,包括整型和浮点型
(6)userdata ,自定义数据格式
(7)thread,协程
(8)table,表
表,不是指数据库中的表,而是一种数据类型,类似于map,用k-v的方式来表现,理论上来讲,除了nil,其它字符都可以作为k 值(索引值)
格式
类似于hash
tableName={
k=v,
}
类似于数组 -- 下标是从1开始
tableName={v,v,v}
可以用hash 格式和 array 格式混搭
x={11,22,33};
y={44,55,66};
t1={
{11,22,33},
{44,55,66}
};
--table.concat(list, sep, i, j) 将数组中的元素拼接成一个字符串
--table.remove(list, pos) 删除数组中元素,默认删除最后一个
--table.insert(list, pos, value) 向指定位置插入元素,默认插入到最后
--table.sort(list, comp) 数组排序,默认从小到大,可自定义排序规则
--table.move(a1, f, e, t, a2) 把数组a1中的元素往a2中拷贝
t1={"abc","DEF","xyz","123","456"};
print(table.concat(t1,"--"));
table.remove(t1,2);
print(table.concat(t1,"--"));
table.insert(t1,2,"123456");
print(table.concat(t1,"--"));
table.sort(t1);
print(table.concat(t1,"--"));
function func1(a,b)
return a>b;
end
table.sort(t1,func1);
print(table.concat(t1,"--"));
print("\n");
t2={"a","b"};
table.move(t1,1,2,3,t2);--把t1 里面的元素拷贝到t2 中
print(table.concat(t1,"--"));
print(table.concat(t2,"--"));
for 循环遍历
for k,v in pairs(tableName) do
print(k,v);
end
c++ 中 pairs 是对组
循环嵌套
for k,v in pairs(info3) do
print(k,"===",v);
if type(v)=="table" then
for k2,v2 in pairs(v) do
print("\t",k2,"===",v2);
end
end
end
6.基本运算符
--[[
赋值=
lua 中变量是弱类型,就是说变量名是没有类型的,其类型取决于所赋的值,并且,同一个变量,可以随时切换成不同的数据类型
多重赋值
a,b=b,a 值交换 类似于swap
算术运算符
加+,减-,乘*,除/,取模%,指数(次方)^
关系运算符
等于==, 不等于~=, 大于>, 小于<, 大于或等于>=, 小于或等于<=
关系运算符的运算结果只能是true 或 false,且只能在相同类型的数据间运算(运算时不会做隐式类型转换)
对于对象型的数据(function,userdata,table),比较运算是比较其引用
逻辑运算符
逻辑与 and, 逻辑或 or, 逻辑非 not
&&, ||, !
在lua 中,逻辑运算与其它语言的逻辑运算不是同一个意思,其运算结果返回值是参与运算的变量之一(not 除外,not 只返回true 或 false)
其它语言的逻辑运算,返回值是0 或 1(false 或 ture),意思就是返回一个bool 值
在lua 中,只有 nil(null,NULL) 和 false 为假,其它都为真(包括空串或0值)
对于and 和 or,实行短路运算(又称短路规则,短路求值,就是说,当前面的表达式可以返回时,就直接返回,不管后面的表达式)
]]
info1={a='a',b='b'};
info2={a='a',b='b'};
info3=info1;
print(info1 == info2);--false 比较的是引用
print(info1 == info3);--true 比较的是引用
print(info1.a == info2.a);--true 比较的是值
print(info1.a);
info3.a='aaa';
print(info1.a);
a,b=1,2;
print(a and b);--如果a 为真,则返回b
a=nil;
print(a and b);--如果a 不为真,则返回a,不再往后运算(不管b是啥)
print("\n");
c,d=1,false;
print(c or d);--如果 c 为真,则返回c,不再往后运算(不管d 是啥)
c=nil;
print(c or d);--如果 c 不为真,则返回d
print("\n");
e,f=1,2;
--print(e not f); --错误写法
print(not e);--如果e为真,则返回假
f=false;
print(not f);--如果f 为假,则返回真
7.流程控制
(1)判断语句
流程控制语句
if 条件 then
...
end
(2)循环语句
while 条件 do
...
end
repeat
...
until 条件;
while 和 repeat 的区别
while 循环中,当条件不成立时,结束循环
repeat 循环中,当条件成立时,结束循环
没有 continue
break 只能跳出一重循环
goto FLAG 语句 跳转到指定标记处,也可用于跳出循环,FLAG是一个标记位,相当于一个锚点
两者区别是
break 只能跳出当前循环,而goto 可以跳转到指定位置,这样可以忽略一些代码
在lua 中,没有这些运算符 i++, i--, ++i, --i, +=, -=
a=b=1 这种写法会出错,不能连续赋值
--求和 1+2+3+...100 5050
i,sum=0,0;
while i<100 do
if i>49 then
goto FLAG;
--break;
end
i=i+1;
sum=sum+i;
end
print(i,sum);
print("111111");
::FLAG::
print("222");
i,sum=0,0;
repeat
i=i+1;
sum=sum+i;
until i>=100;
print(i,sum);
for 循环分为数值循环和泛型循环(类似于foreach)
数值循环
for 变量名=初始值,结束值,步长(默认值为1,可省略) do
...
end
泛型循环
for k,v in 迭代函数(table) do -- 此处 v 可以省略,k 不能少
...
end
迭代函数 ipairs,pairs
ipairs 顺序遍历,中间的序号不会断开,遇到k=>v 直接跳过,遇到第一个nil 就会直接终止,一般情况下,用于数组类型的集合遍历
pairs 遇到nil 会跳过,同时适用数组类型和k=>v 类型的集合,混搭也是没问题的,如果是混搭的时候,会优选获取数组类型数据
pairs 的适用范围大于 ipars
如果使用时不确定用哪个,就无脑pairs
(3)goto语句
--[[
流程控制语句
goto FLAG 语句 跳转到指定标记处,也可用于跳出循环,FLAG是一个标记位,相当于一个锚点
代码块(作用域) do ... end
flag 不可见原则
1 不能从外面 goto 到代码块里面,因为代码块里面的flag,对于外面的 goto来说,是不可见的
2 不能跳出或跳入一个函数,因为函数也是一个block(块)
3 不能跳入本地变量(local)作用域
]]--
do
a=123;
::FLAG1::;
print(a);
::FLAG2::;
goto FLAG1;--此处goto 是在 local b 的作用域外面,所以报错
local b=456;
::FLAG3::;
print(b);
--goto FLAG1;--此处goto 是在 local b 的作用域里面
end
--print(a);
--print(b);
--[[
function func1()
::FLAG1::;
print("func1--11");
print("func1--22");
goto FLAG3;
::FLAG2::;
print("func1--33");
::FLAG3::;
end
::FLAG4::;
print("aaaa");
func1();
::FLAG5::;
print("bbb");
]]--
--[[
print("1234");
goto FLAG1;
do
print("a");
print("b");
::FLAG1::;
print("c");
print("d");
::FLAG2::;
end
::FLAG3::;
print("aa");
print("bb");
::FLAG4::;
print("cc");
print("dd");
]]--
--死循环
--[[
i=0;
::FLAG1::;
print(i);
i=i+1;
goto FLAG1;
]]--