Fork me on GitHub

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
View Code

使用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
> 
View Code

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
View Code

与许多动态语言类似,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会把第一个.算成小数点,而不是连接符..

 

 

 

 

 

posted @ 2018-12-21 21:40  克拉默与矩阵  阅读(1236)  评论(0编辑  收藏  举报