Lua快速教程
前言
Lua 是一个小巧的脚本语言。是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组,由 Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo 所组成并于 1993 年开发。其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。Lua 由标准 C 编写而成,几乎在所有操作系统和平台上都可以编译、运行。Lua 并没有提供强大的库,这是由它的定位决定的。所以 Lua 不适合作为开发独立应用程序的语言。
Lua 脚本可以很容易的被 C/C++ 代码调用,也可以反过来调用 C/C++ 的函数,这使得 Lua 在应用程序中可以被广泛应用。不仅仅作为扩展脚本,也可以作为普通的配置文件,代替 XML、ini 等文件格式,并且更容易理解和维护。本文涉及到的演示均在Linux下进行
Lua退出
不先讲运行,直接讲退出。没错,因为运行Lua太简单了,简单到直接输入lua就可以了。但是退出确有必要单独说下,很多人在lua交互界面会试着使用exit退出,结果发现然并卵,与似乎干脆Ctrl + C干死lua。正确的推出姿势是这样婶的,有两种方式
①Ctrl+D
②os.exit()
Lua执行
在lua交互式环境下,你可以输入一些较短的命令,类似于Python。但是要想处理复杂逻辑,就需要单独放在文件中了。lua交互模式下如何执行一个文件?这个也很简单lua xxx.lua,和Python用法一样。但是你如果非要在交互式环境下执行lua脚本呢?也可以,使用dofile函数
learn.lua脚本
function norm(x,y) return(x^2+y^2)^0.5 end function twice(x) return 2*x end
使用dofile函数加载lua脚本到交互模式下
[root@localhost learn]# lua Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio > dofile("/root/learn/learn.lua") > n=norm(3.4,1.0) > print(n) 3.5440090293339 > print(twice(n)) 7.0880180586677 >
Lua语法
注释
--单行注释
--[[ --]]多行注释
类型与值
与C/C++不同,Lua是动态类型语言。Lua中变量没有类型,值才有类型,值本身携带自己的类型信息。Lua中有8种基础类型:nil(空)、boolean(布尔)、number(数字)、string(字符串)、userdata(自定义类型)、function(函数)、thread(线程)和table(表)。函数type 可根据一个值返回其类型名称。
nil
就是C/C++中的NULL。
Lua中的变量,没有初值时,其值为nil。当变量赋值为nil时,相当于删除,相当于与一块内存断开联系。当一块内存不在于任何变量有联系的时候,Lua垃圾收集器会回收内存。
boolean
用法同C/C++一样,但是有点小细节要注意
false:false、nil
true:0、空串
number
Lua中number默认相当于C/C++中的双精度浮点数,Lua中没有整数类型。写法上,和C/C++一样,支持多种表示方式
4 0.4 4.57e-3 0.3e12 5e+20
string
Lua的字符串是不可变的值(immutable values)。不能像在C语言中那样直接修改字符串的某个字符,而是应该根据修改要求来创建一个新的字符串。如下所示:
a = "one string" b = string.gsub(a,"one","another") print(a) -->one string print(b) -->another string
与许多动态语言类似,Lua也支持自动内存管理,很爽是不是!
关于string还有以下几点需要注意
①\number,即用ASCII表示字符
②支持引号内部嵌套引号
print("one 'two' \"string\"") -->one 'two' "string"
③支持[[ ]]形式字符串
比如可以定义变量
c_code = [[ lua_getglobal(L,"str"); string str = lua_tostring(L,-1); cout<<"str = "<<str.c_str()<<endl; ]]
这种形式定义的变量有两个特点:
1、[[后的第一个换行符会忽略
2、忽略[[ ... ]]内部的转义序列
这种形式定义的变量有两个潜在问题:
1、[[ ... ]]内部如果包含 a=b[c[i]] 这样的语句,可能会提前结束字符串定义
2、[[ ... ]]包含多行注释的情况,--]]可能会提前结束字符串定义
Lua的解决方案和CMake中多行注释是一个套路,即采用这种对称的这种符号[===[,等号数量任意
④某些情况西,Lua会自动进行字符串⇆数字的强制转换
print("10"+1) -->11 字符串⇛数字 print(10 .. 1) -->101 数字⇛字符串,注意10后面有个空格,否则Lua会把第一个.算成小数点,而不是连接符..
强烈不建议这种代码,可读性非常差。而是应该显式进行 字符串⇆数字 转换
print(tostring(10)=="10") -->true print(tonumber("10")==10) -->true
⑤#可以获取字符串长度
print(#"hello") -->5
table
Lua中的模块(module)、包(package)和对象(object)都是通过table来组织的。
当输入io.read的时候:
站在人的角度理解 ▶ io模块中的read函数
站在Lua的角度理解 ▶ 以字符串“read”作为key来索引table.io
Lua中的table跟其他语言中的字典是一个东西,除了可以使用数字索引外(Lua中数字索引从1开始),可以用任何其他类型的值作为table索引。
a.x 等价于 a["x"] a[x] 表示取完x的值后再索引
#可以计算一个string的长度,同样也可以计算一个table的长度,table计算长度的方式类似于C/C++中字符串求长度知道遇到\0,table遇到nil就认为table结束了。
a={} a[1000]=1 print(#a) --> 0 print(table.maxn(a)) --> 1000
这种table类似于Linux下面空洞文件的概念,table中1~999都是nil,也就是有洞。因此print(#a)输出0。如果真需要处理“有洞”的table,可以使用函数table.maxn返回一个table的最大正索引数。
操作符
算数操作符
+ -(减法) * / % ^ -(负号)
与C/C++用法一样,单独说下%
Lua中 a%b 结果正负号与b相同
当x为实数时 x % 1 -->x的小树部分 x - x % 1 -->x的整数部分 x - x % 0.01 -->x精确到小数点后两位
关系操作符
< > <= >= == ~=
与C/C++用法一样。关系操作符所作的工作本质上是比较,比较分为值比较,引用比较。Lua中table、userdata、function属于引用比较
a = {};a.x = 1; a.y = 0 b = {};a.x = 1; a.y = 0 a = c --------------------------------------- 结果是 a == c a ~= b
逻辑操作符
and or not
这是我第一个地方觉得Lua设计非人类的地方,主要原因是and or的用法原大多数语言都不一样,想不明白Lua为啥要搞成这样
and:如果第一个操作数为假,就返回第一个操作数,否则返回第二个操作数。
or: 如果第一个操作数为真,就返回第一个操作数,否则返回第二个操作数。
字符串连接符
..
Lua中的字符串是不可变的值(immutable value)。连接操作符只会创建一个新字符串,而不会对其原操作数进行任何修改
此外在对数字使用..的时候,..需要与数字之间留有空格
print("10"+1) -->11 字符串⇛数字 print(10 .. 1) -->101 数字⇛字符串,注意10后面有个空格,否则Lua会把第一个.算成小数点,而不是连接符..