Lua是一门神奇的语言。
教程基本上是从网上找的……
配置
从上面的站找吧,下载下来安装就好。
安装下之后会有两个可执行文件,一个是命令行的Lua(Command line),一个是SciTE。
print("Hello World!")
这样一行程序就可以完成java用了5行,c++用了4行的代码。这门语言的确十分简洁。
还有一点必须说,Lua这个语言非常自由,你想加分号不想加分号都随喜好,不过个人习惯问题我就加上了。
那么如何运行呢?一般有两种用法:
一种是交互式编程。这个很简单,打开Lua(Command line),然后输入上述代码,回车,运行完成。
效果如下:
一种是脚本式编程。这就是我们平时写其它语言用的方法,将文件保存在*.lua文件中然后用SciTE运行即可。SciTE可以看成一个轻量级IDE,支持语法高亮等。不过因为个人习惯,写代码的时候还是会用VSC。效果差不多是这个样子,运行结果会在底下显示出来:
数据类型
lua的数据类型有8种,但没有其它语言中所谓的整型、长整型、单精度浮点型等。
nil型
nil型即无效值,简单来说就是空型,值只有一种就是nil。举个栗子,没有初始化的变量就是nil型。
type()函数返回一个字符串表示变量类型。我们可以用这个函数来查看一些奇怪的东西。
print(type(a)) --Output:nil
上述代码输出了a的值。由于a未初始化,因此输出nil。顺便一提,–表示注释,与很多语言不同,这点还请注意。
nil还可以用于删除一个变量。
a=10;
print(type(a)); --Output:number
a=nil;
print(type(a)); --Output:nil
布尔型
老朋友了,自不必多说。boolean型有两个值:true/false。顺便一提nil也属于false。
a=nil;
b=false;
c=true;
d=10.45;
e=0;
f="asdfghjkl";
if a then
print("A It's true");
end
if b then
print("B It's true");
end
if c then
print("C It's true"); --Have Output
end
if d then
print("D It's true"); --Have Output
end
if e then
print("E It's true"); --Have Output
end
if f then
print("F It's true"); --Have Output
end
我们发现,除去nil和false,所有的变量不论值为何都为true。尤其是变量e,值为0仍然为true,这意味着我们不能用if(e)这种简洁的表示方法。
数值型
Number型很特别,在Lua中Number默认为双精度浮点型。在luaconfig.h中可以设置,不过感觉意义不大。
顺便一提这个是支持科学计数法的,如
a=2e+1
b=7.67986e-9
c=4.54345e9
这些表述都是允许的。
也因此,我们非常常用的a/b不能取到取整效果。不过也用不到吧orz
字符串
lua中的string比较特别。
字符串的定义
定义一个字符串,可以用” “,可以用’ ‘,原因很简单,反正没有char这种东西。
a="123"
a='123'
此外,如果有多行的话字符串可以用一组中括号定义:
a=[[
1 1 0 1
0 0 1 1
0 1 0 0
0 0 1 1
]];
print(a);
这样的字符串是有格式的,输出结果:
别想了这玩意没法存图
字符串的运算符
算术运算符
遇见+/-/*/%等操作符时将会试图将字符串转换成数字运算
当然是没法转换的时候会报错
a='3';
b='7';
c=a+b;
d=b%a;
print(c); --Output:10
print(type(c)); --Output:number
print(d); --Output:1
这是非常有效的特性(极大的减少了-‘0’)
..运算符
用于连接字符串或与其它类型连接,如上栗中
print(a..b) --Output:37
print(a..b+c) --Output:317
print((a..b)+c) --Output:47
print(a..b..c) --Output:3710
print(type(a..b..c)); --Output:String
不过nil还是算了,大概会报错。
#运算符
用于显示长度,相当于length();
a=[[
1 1 0 1
0 0 1 1
0 1 0 0
0 0 1 1
]];
b='asdfghjkl';
print(#a); --Output:32
print(#b); --Output:9
表
table可以看做map
a={}; --创建空表
a["key"]=10; --"key"为键值
print(a["key"]); --Output:10
zima=17;
a[zima]="17!"; --17为键值
print(a[17]); --Output:17!
b={"QAQ","QWQ"};
for k,v in pairs(b) do --迭代遍历,k为键值,v为值
print(v,":",k);
end
--[[Output:
QAQ : 1
QWQ : 2
顺便一提多行注释就是这么写
]]
c={r="l",q="f","g",q="s"}; --直接定义的方法
for k,v in pairs(c) do
print(k.. "-" ..v);
end;
--[[Output:
1-g
q-s
r-l
]]
同map一样,table的元素会按照字典序排序,且不允许重复。
从b数组的输出来看,table有一个很奇妙的特性:在我们建一个非空的表时,若为指定,默认会以number为类型下标从1开始标记。
没错,是从1!简直是福利,只要不要记错。
我们看到建立有两种方式,一种是直接定义好,一种是建空表慢慢插入。调用的方法的话,键值为string型可以以b.q
这种方式调用,而数值与字符串键值均可以用b[q]
来调用。
table这玩意大小可随时增加减少。想要删除的话可以用一下nil:
a[zima]=nil;
for k, v in pairs(a) do
print(k .. " - " .. v)
end
--[[Output:
key - 10
]]
c.q=nil;
c.r=nil;
for k,v in pairs(c) do
print(k.. "-" ..v);
end;
--[[Output:
1-g
]]
函数
function类型……嗯总之就是这么个类型
function cmp(a,b)
if #a>#b then
return a;
else
return b;
end
end
a="afd";
b="asddf";
print(cmp(a,b)); --Output:asddf
func=cmp;
print(func(a,b)); --Output:asddf
也由于它是个类型,所以还可以做到匿名函数这种操作:
function a(a,b,cmp)
print(cmp(a,b));
end
a(5,6,function(a,b)
if a>b then
return true;
else
return false;
end
end);
--Output:false
线程
总之这玩意支持多线程。
先知道这个就好了
自定义类型
可以用struct,指针等。之后再说。
变量
变量这东西还是蛮有趣的。
变量的作用域比较特别,除非特别用local关键字标出,否则一切变量都是全局变量,无论是在语句中还是函数中。举个栗子:
function f(a,b)
c=a;
local d=b;
a,b=b,a;
return a,b;
end
m,n=f(3,4);
print(a,b,c,d,m,n);
--Output:nil nil 3 nil 4 3
显然,除了由于语言特性自动变成局部变量的a,b外,函数体内的c是一个全局变量而使用了local关键字的d是局部变量。
顺便一提,a,b=b,a
这种操作是比较特有的,可以交换a,b。没错,可以交换a,b。就是有这种操作。
赋值操作可以同时付给多个值,如上栗中m,n=f(3,4)
就是一个栗子。也因此有个问题:多退少补,给多值了就会被编译器姬吃掉,给少了就会补上nil。因此,a,b,c=0;
只会给a赋0,b,c均为nil。这点还请注意。
运算符
运算符就比较简单了。唯一令人不爽的是,没有三目运算符和位运算符。没法压行了桑心。
算术运算符有 + - * / % ^,不过^不是按位异或,而是幂。此外-有减的意思也有负号的意思。
关系运算符方面,有 == ~= > < >= <=6个。~=就是不等于,除此之外与其他语言是一致的。
逻辑运算符有 and or not,不是&|!而是and or not,含义倒是没什么区别。
此外还有两个运算符,一个是..,用来连接,已经说过了;另一个是#,也已经说过了,用来查看string和table的长度,相当于C++的size()函数。
那么运算符优先级:
^ | |||||
---|---|---|---|---|---|
not | - | ||||
* | / | ||||
+ | - | ||||
.. | |||||
< | > | <= | >= | ~= | == |
and | |||||
or |
基本结构的实现
顺序结构
略
选择结构
这门语言确实是非常的不拘小节。
if语句
if 布尔表达式 then
--[[
......
]]
end
布尔表达式可加括号可不加。嗯……
类似其它语句的,我们有
if else
if 布尔表达式 then
--......
else
--......
end
if elseif else
a=5;
if a>7 then
a=a+1;
elseif a>5 then
a=a+2;
else
a=a-0.8;
end
print(a); --Output:4.2
注意Lua的else和if是连起来的……
循环结构
while
举个栗子吧
a=3;
while a<=5 do
a=a+1;
end
print(a); --Output:6
原汁原味的while
数值型for
在Lua中for分为数值型与泛型。后者有些类似java中的foreach,我们先来说前者。
for 初值,结束值,变化幅度 do
--......
end
举个栗子
a={"Sunday","Monday","Tuesday","Wednesday",
"Thursday","Friday","Saturday"};
for i=7,1,-1 do
print(a[i]);
end
--[[Output:
Saturday
Friday
Thursday
Wednesday
Tuesday
Monday
Sunday
]]
顺便一提第三个参数可不选。
泛型for
这玩意很有趣,先看个例子。
a={"Sunday","Monday","Tuesday","Wednesday",
"Thursday","Friday","Saturday"};
for i,v in ipairs(a) do
print(i .. ":" .. v);
end
a.other="xingqiba";
for i,v in ipairs(a) do
print(i .. ":" .. v);
end
for i,v in pairs(a) do
print(i .. ":" .. v);
end
前两次输出一样,而第三次则多了一行
other : xingqiba
这说明:ipairs会按照数值键值遍历,pairs按照键值全部遍历。具体的学完数组再说吧。
repeat until
原汁原味的do while.
嗯……
repeat
--......
until 布尔表达式
就是这么写
break
原汁原味的break……跳出循环……