什么是lua
Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
lua特性
- 轻量级: 它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。
- 可扩展: Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。
- 其它特性:
- 支持面向过程(procedure-oriented)编程和函数式编程(functional programming);
- 自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象;
- 语言内置模式匹配;闭包(closure);函数也可以看做一个值;提供多线程(协同进程,并非操作系统所支持的线程)支持;
- 通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承和重载等。
Lua 应用场景
- 游戏开发
- 独立应用脚本
- Web 应用脚本
- 扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench
- 安全系统,如入侵检测系统
第一个lua程序
print("hello world")
lua变量/类型
table1 = {"test4",key1="test1",1,"test5",6,key2="test2","test3"}
for k,v in pairs(table1) do
print(k.."-"..v) -- lua中 字符串连接使用..
end
print("11111111111111111111111")
table1.key1 = nil
for k, v in pairs(table1) do
print(k.."-"..v)
end
-- 对于全局变量和table,nil也可以用作删除,对全局变量或table里面变量赋一个nil值,等同于将其删掉。
-- nil作比较时,需加上""
print(type(x)) -- nil
print(type(x)==nil) -- false
print(type(x)=="nil") --true
-- type(x)实质就是返回一个字符串格式的"nil",类型是string。
-- boolean类型只有两个可选项,true和false,lua把false和nil看作是false,剩下的全为true,数字0也是true。
print(type(true)) -- true
print(type(false)) -- false
print(type(nil)) -- false
if fasle or nil then
print("至少有一个是true")
else
print("都是false")
end
if 0 then
print("true")
else
print("false")
end
-- lua默认只有一种number类型-double(双精度)类型 示例:
print(type(2))
print(type(2.2))
print(type(print))
print(type(type))
print(type(nil))
print(type(x))
-- nil类型表示没有任何有效值 只有一个值 nil 打印一个没有被赋值的变量 就会输出nil
print(type(a))
print(x)
-- string 字符串类型 由一对""或是''表示,也可以使用两个方括号[[]]来表示"一块"字符串
str1 = "tomtao"
str2 = 'tomtao626'
str3 = [[
<html>
<head>title</head>
<h1>tomtao</h1>
<body>
<a href="https://blog.tomtao626.com">test123</a>
</body>
</html>
]]
print(str1)
print(str2)
print(str3)
-- 在lua中,对一个数字字符串进行算数操作时,lua会尝试将其转换成一个数字
print("2"+5) -- 7.0
print("2"+"5") -- 7.0
print("2 + 5")
print(2+5)
print("2".."5")
print("error"..1)
-- 获取数据长度 #
print("获取数据长度")
len = "blog.tomtao626.com"
print(#len) -- 14
print(#"blog.tomtao626.com") -- 14
-- table 表 通过构造表达式来完成 {} 创建一个空表
-- 创建一个空表
local tb1 = {}
-- 创建初始化表
local tb2 = {"apple", "tomtao", "orange", "pear"}
-- lua中的表其实就是一个关联数组 数组的索引可以是数字或者字符串
a = {}
a["key"] = "value"
key = 10
a[key] = 666
a[key] = a[key] + 333
for k,v in pairs(a) do
print(k .. ":" .. v)
end
-- lua表内的初始索引一般以1开始
for key, val in pairs(tb2) do
print("key", key)
end
-- key 1
-- key 2
-- key 3
-- key 4
-- table不会固定长度大小,有新数据增加时长度会自增,未初始化的table都是nil
a3 = {}
for i=1,10 do
a3[i] = i
end
a3["key"] = "val"
print(a3["key"]) -- val
print(a3["none"]) -- nil
-- function 函数 函数可以存在变量内
function factorial(n)
if n == 0 then
return 1
else
return n * factorial(n-1)
end
end
print(factorial(5))
fac = factorial(5)
print(fac)
fac2 = factorial
print(fac2(5))
-- function 通过匿名函数方式进行参数传递
function testFun(tab, fun)
for k,v in pairs(tab) do
print(fun(k,v));
end
end
tab = {key1="val1", key2="val2"};
testFun(tab, function(key, val)
return key .. ":" .. val;
end);
-- userdata 自定义数据
-- 用于表示一种由应用程序或 C/C++ 语言库所创建的类型,
-- 可以将任意 C/C++ 的任意数据类型的数据(通常是 struct 和 指针)存储到 Lua 变量中调用
-- lua 变量有三种类型 全局变量 局部变量 表中的域
-- lua内的变量全是全局变量 不论是在语句内或是函数内 但是可以用local显式声明
-- 局部变量的作用域为从声明位置开始到所在语句块结束
-- 变量默认值为nil
a = 5
local b = 5
function joke()
c = 5
local d = 6
end
joke()
print(c,d) -- 5 nil
do
local a = 6 -- a 是局部变量
b = 6
print(a, b) -- 6 6
end
print(a,b) -- 5 6
-- 赋值语句
x = "hello" .. "world"
--t.n = t.n + 10
print(x)
a,b = 10, 2*10
x, y = y,x
a,b,c = 0,1 -- a=0,b=1,c=nil
a,b = a+1, b+1, b+2 -- value of b+2 is ignored
print(a, b) -- 1 2
a,b,c = 0 -- a=0,b=nil,c=nil 注意:如果要对多个变量赋值必须依次对每个变量赋值。
print(a,b,c)
--多值赋值经常用来交换变量,或将函数调用返回给变量:
--
function f()
return 1, 2
end
a, b = f()
--f()返回两个值,第一个赋给a,第二个赋给b。
--
--应该尽可能的使用局部变量,有两个好处:
--
--1. 避免命名冲突。
--2. 访问局部变量的速度比全局变量更快。
-- 索引 对 table 的索引使用方括号 []。Lua 也提供了 . 操作。
site = {}
site['key'] = "blog.tomtao626.com"
print(site['key'])
print(site.key)
循环/逻辑运算
-- lua 变量有三种类型 全局变量 局部变量 表中的域
-- lua内的变量全是全局变量 不论是在语句内或是函数内 但是可以用local显式声明
-- 局部变量的作用域为从声明位置开始到所在语句块结束
-- 变量默认值为nil
a = 5
local b = 5
function joke()
c = 5
local d = 6
end
joke()
print(c,d) -- 5 nil
do
local a = 6 -- a 是局部变量
b = 6
print(a, b) -- 6 6
end
print(a,b) -- 5 6
-- 赋值语句
x = "hello" .. "world"
--t.n = t.n + 10
print(x)
a,b = 10, 2*10
x, y = y,x
a,b,c = 0,1 -- a=0,b=1,c=nil
a,b = a+1, b+1, b+2 -- value of b+2 is ignored
print(a, b) -- 1 2
a,b,c = 0 -- a=0,b=nil,c=nil 注意:如果要对多个变量赋值必须依次对每个变量赋值。
print(a,b,c)
--多值赋值经常用来交换变量,或将函数调用返回给变量:
--
function f()
return 1, 2
end
a, b = f()
--f()返回两个值,第一个赋给a,第二个赋给b。
--
--应该尽可能的使用局部变量,有两个好处:
--
--1. 避免命名冲突。
--2. 访问局部变量的速度比全局变量更快。
-- 索引 对 table 的索引使用方括号 []。Lua 也提供了 . 操作。
site = {}
site['key'] = "blog.tomtao626.com"
print(site['key'])
print(site.key)
函数
-- 函数
--- optional_function_scope function function_name( argument1, argument2, argument3..., argumentn)
--- function_body
--- return result_params_comma_separated
--- end
-- optional_function_scope: 该参数是可选的制定函数是全局函数还是局部函数,未设置该参数默认为全局函数,如果你需要设置函数为局部函数需要使用关键字 local。
-- function_name: 指定函数名称。
-- argument1, argument2, argument3..., argumentn: 函数参数,多个参数以逗号隔开,函数也可以不带参数。
-- function_body: 函数体,函数中需要执行的代码语句块。
-- result_params_comma_separated: 函数返回值,Lua语言函数可以返回多个值,每个值以逗号隔开。
--[[ 函数返回两个值的最大值 --]]
function max(num1, num2)
if (num1 > num2) then
result = num1;
else
result = num2;
end
return result;
end
-- 调用函数
print("两值比较最大值为 ",max(10,4))
print("两值比较最大值为 ",max(5,6))
-- 将函数作为参数传递
myprint = function(param)
print("这是打印函数- ##", param, "##")
end
function add(num1, num2, functionPrint)
result = num1 + num2
-- 调用传递的函数参数
functionPrint(result)
end
myprint(10)
-- myprint作为函数参数传递
add(1,2, myprint)
-- 多返回值
s, e = string.find("blog.tomtao626.com", "tomtao626")
print(s, e)
function maximum (a)
local mi = 1 -- 最大值索引
local m = a[mi] -- 最大值
for i,val in ipairs(a) do
if val > m then
mi = i
m = val
end
end
return m, mi
end
print(maximum({8,10,23,12,5}))
-- 可变参数
-- 函数可以接受可变数目的参数,和 C 语言类似,在函数参数列表中使用三点 ... 表示函数有可变的参数
function add(...)
local s = 0
for i, v in ipairs{...} do --> {...} 表示一个由所有变长参数构成的数组
s = s + v
end
return s
end
print(add(3,4,5,6,7)) -- 25
-- 将可变参数赋值给一个变量
function average(...)
result = 0
local arg={...} --> arg 为一个表,局部变量
for i,v in ipairs(arg) do
result = result + v
end
print("总共传入 " .. #arg .. " 个数")
return result/#arg
end
print("平均值为",average(10,5,3,4,5,6))
-- 也可以通过 select("#",...) 来获取可变参数的数量
function average(...)
result = 0
local arg={...}
for i,v in ipairs(arg) do
result = result + v
end
print("总共传入 " .. select("#",...) .. " 个数")
return result/select("#",...)
end
print("平均值为",average(10,5,3,4,5,6))
-- 有时候我们可能需要几个固定参数加上可变参数,固定参数必须放在变长参数之前
function fwrite(fmt, ...) ---> 固定的参数fmt
return io.write(string.format(fmt, ...))
end
fwrite("tomtao626\n") --->fmt = "tomtao626", 没有变长参数。
fwrite("%d%d\n", 1, 2) --->fmt = "%d%d", 变长参数为 1 和 2
-- 通常在遍历变长参数的时候只需要使用 {…},然而变长参数可能会包含一些 nil,那么就可以用 select 函数来访问变长参数了:select('#', …) 或者 select(n, …)
-- select('#', …) 返回可变参数的长度。
-- select(n, …) 用于返回从起点 n 开始到结束位置的所有参数列表。
-- 调用 select 时,必须传入一个固定实参 selector(选择开关) 和一系列变长参数。如果 selector 为数字 n,那么 select 返回参数列表中从索引 n 开始到结束位置的所有参数列表,否则只能为字符串 #,这样 select 返回变长参数的总数。
function f(...)
a = select(3,...) -->从第三个位置开始,变量 a 对应右边变量列表的第一个参数
print (a)
print (select(3,...)) -->打印所有列表参数
end
f(0,1,2,3,4,5)
do
function foo(...)
for i = 1, select('#', ...) do -->获取参数总数
local arg = select(i, ...); -->读取参数,arg 对应的是右边变量列表的第一个参数
print("arg", arg);
end
end
foo(1, 2, 3, 4);
end
lua包(module)
--- 模块类似于一个封装库,从 Lua 5.1 开始,Lua 加入了标准的模块管理机制,
--- 可以把一些公用的代码放在一个文件里,以 API 接口的形式在其他地方调用,有利于代码的重用和降低代码耦合度。
--- Lua 的模块是由变量、函数等已知元素组成的 table,
--- 因此创建一个模块很简单,就是创建一个 table,然后把需要导出的常量、函数放入其中,最后返回这个 table 就行。
-- 文件名为 module.lua
-- 定义一个名为 module 的模块
module = {}
-- 定义一个常量
module.constant = "这是一个常量"
-- 定义一个函数
function module.func1()
io.write("这是一个公有函数!\n")
end
local function func2()
print("这是一个私有函数!")
end
function module.func3()
func2()
end
return module
-- 使用require函数来加载模块
-- require("<模块名>") 或者 require"<模块名>"
-- test_module.lua 文件
-- module 模块为上文提到到 module.lua
require("<module>")
print(module.constant)
module.func3()
-- test_module2.lua 文件
-- module 模块为上文提到到 module.lua
-- 别名变量 m
local m = require("module")
print(m.constant)
m.func3()