简介
Lua 是一个小巧的脚本语言。它是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个由Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo三人所组成的研究小组于1993年开发的。 其设计目的是为了通过灵活嵌入应用程序中从而为应用程序提供灵活的扩展和定制功能。Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。Lua并没有提供强大的库,这是由它的定位决定的。所以Lua不适合作为开发独立应用程序的语言。Lua 有一个同时进行的JIT项目,提供在特定平台上的即时编译功能。
Lua脚本可以很容易的被C/C++ 代码调用,也可以反过来调用C/C++的函数,这使得Lua在应用程序中可以被广泛应用。不仅仅作为扩展脚本,也可以作为普通的配置文件,代替XML,ini等文件格式,并且更容易理解和维护。 Lua由标准C编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以编译,运行。 一个完整的Lua解释器不过200k,在所有脚本引擎中,Lua的速度是最快的。这一切都决定了Lua是作为嵌入式脚本的最佳选择。
特性
轻量级
Lua语言的官方版本只包括一个精简的核心和最基本的库。这使得Lua体积小、启动速度快,从而适合嵌入在别的程序里。5.0.2版的Lua的内核小于120KB,而Python的内核大约860KB,Perl的内核大约1.1MB。
可扩展
Lua并不象其它许多"大而全"的语言那样,包括很多功能,比如网络通讯、图形界面等。但是Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。
其它特性
Lua还具有其它一些特性:同时支持面向过程(procedure-oriented)编程和函数式编程(functional programming);自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象;语言内置模式匹配;闭包(closure);函数也可以看做一个值;提供多线程(协同进程 ,并非操作系统所支持的线程)支持;通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承和重载等。
一些简单操作
数组
-- 定义一个数组
cities = {"北京", "上海", "广州"}
cities[4] = "深圳"
for i = 1, 4 do
print("cities["..i.."]"..cities[i])
end
-- 排序(逆序)
table.sort(cities, function(a,b)
return a > b
end
)
print(table.concat(cities))
map
cities = {"北京", "上海", "广州"}
cities[4] = "深圳"
-- 定义一个map
emp = {name="张三", age=23, depart="销售部"}
-- 下标操作
emp["gender"] = "男"
print(emp["name"])
print(emp["gender"])
-- 点号方式操作
emp.office = "2nd floor"
print(emp.age)
print(emp.office)
模块
--~ 声明一个模块
rectangle = {}
--~ 为模块添加变量
rectangle.pi = 3.14
--~ 为模块添加函数(求周长)
function rectangle.perimeter(a, b)
return (a + b) * 2
end
--~ 为模块添加函数求面积(以匿名函数)
rectangle.area = function(a, b)
return a * b
end
return rectangle
--~ 导入一个模块
require "rectangle"
-- 访问模块属性,调用模块函数
print(rectangle.pi)
print(rectangle.perimeter(3, 5))
print(rectangle.area(3, 5))
元表
cities = {"北京", "上海", "广州"}
cities[4] = "深圳"
--~ 声明一个元表
meta = {
__tostring = function(tab)
str = ""
for k, v in pairs(cities) do
str = str.." "..k..":"..v
end
return str
end
}
--~ 将元表与原始表相连
setmetatable(cities, meta)
print(cities)
对象
-- 创建animal对象
animal = {name = "Tom", age = 5}
function animal:bark(voice)
print(self.name.."在"..voice.."叫")
end
animal:bark("喵喵")
animal2 = animal
animal = nil
animal2.name = "Jerry"
animal2:bark("汪汪")
类
-- 定义创建类
Animal = {name = "no_name", age = 0}
function Animal:bark(voice)
print(self.name.."在"..voice.."叫")
end
-- 为该类创建一个无参构造器
function Animal:new()
--~ --~ 创建一个新表
local a = {}
--~ -- 为新表指定元素为当前基础类表
setmetatable(a, {__index=self})
--~ -- 返回新表
return a
end
--~ -- 为该类创建一个带参的构造器 (参数为table)
function Animal:new(obj)
local a = obj or {}
setmetatable(a, {__index=self})
return a
end
animal = Animal:new()
animal2 = Animal:new()
animal3 = Animal:new({type = "老鼠"})
--~ -- print(animal)
--~ -- print(animal2)
animal2.name = "Tom"
animal2.age = 5
animal2.type = "猫"
print(animal2.name.."今年"..animal2.age.."岁了,它是一只"..animal2.type)
animal3.name = "Jerry"
animal3.age = 4
print(animal3.name.."今年"..animal3.age.."岁了,它是一只"..animal3.type)
协同线程
--~ -- 创建一个协同线程实例
crt = coroutine.create(
function(a, b)
print(a, b, a + b)
-- 获取正在运行的协同线程实例
tr = coroutine.running()
-- 查看协同线程实例的类型
print(type(tr))
-- 查看协同线程实例的状态
print(coroutine.status(crt))
-- 挂起当前的协同线程实例
coroutine.yield()
print("又重新回到了协同线程")
end
)
-- 启动协同线程实例
coroutine.resume(crt, 3, 5)
-- 查看crt的类型
print("main-"..type(crt))
-- 查看协同线程实例的状态
print("main-"..coroutine.status(crt))
-- 继续执行协同线程
coroutine.resume(crt)
-- 查看协同线程实例的状态
print("main-"..coroutine.status(crt))
协同函数
-- 创建协同函数
cf = coroutine.wrap(
function(a, b)
print(a,b)
--获取当前协同函数创建的协同线程
tr = coroutine.running()
print("tr的类型为:"..type(tr))
--挂起当前的协同线程
coroutine.yield(a+1, b+1)
print("又重新回到了协同线程")
return a+b, a*b
end
)
-- 调用协同函数, 启动协同线程
result1, result2 = cf(3, 5)
print(result1, result2)
print("cf的类型为:".. type(cf))
--重新启动挂起的协同线程
result1, result2 = cf()
print(result1, result2)
IO
静态io
-- 以只读形式打开文件
file = io.open("info.properties", "r")
-- 指定要读取的文件
io.input(file)
-- 每次读取一行数据
line = io.read("*l")
while line ~= nil do
print(line)
line = io.read("*l")
end
-- 关闭文件
io.close(file)
-- 以追加形式打开文件
file = io.open("info.properties", "a")
-- 指定要追加的文件
io.output(file)
-- 写入一行数据
io.write("\ngender=male")
-- 关闭文件
io.close(file)
实例io
-- 以只读形式打开文件
file = io.open("info.properties", "r")
-- 每次读取一行数据
line = file:read("*l")
while line ~= nil do
print(line)
line = file:read("*l")
end
-- 关闭文件
file:close()
-- 以追加形式打开文件
file = io.open("info.properties", "a")
-- 写入一行数据
file:write("\nlevel=p7")
-- 关闭文件
file:close()
seek
-- 以只读形式打开文件
file = io.open("num.txt", "r")
pos = file:seek()
print("当前位置:"..pos)
-- 读取一行数据
line = file:read("*l")
print(line)
pos = file:seek()
print("读取一行数据后的位置:"..pos)
-- 换行符占两个位置
pos = file:seek("set", 2)
print("返回到文件起始位置的后面第2个位置:"..pos)
--接着读取一行数据
line = file:read("*l")
print(line)
pos = file:seek("end", -2)
print("定位到文件最后的位置的前面第二个位置:"..pos)
--读取一行数据
line = file:read("*l")
print(line)
-- 关闭文件
file:close()