Lua应用
# 概述
Lua 是款轻量的脚本语言 , 基于C语言编写实现 , 设计初衷基于嵌入式编程设计 , 随着不断发展 , 也衍生出了很多代码脚本的组合应用
官网 : https://www.lua.org/ (opens new window)
# 应用
Linux 安装
# 更新 yun 包管理器
yum update
# yun 安装 lua
yum install lua
# 验证版本
lua -v
Lua 有两种应用方式 : (以 Hello World为示例)
- 交互式
- 脚本式
交互式
# 通过 -i 实现交互命令 (以下两命令一样)
lua -i
lua
> print("Hello World!");
# 退出 : Ctrl + C
脚本式
创建脚本文件 hello.lua
print("Hello World!");
运行文件
lua hello.lua
提示
lua主要的已脚本形式运作 , 配合代码的应用!
注释
-- 单行注释
--[[
多行注释
多行注释
]]--
# 变量
Lua 脚本 的变量也是采用弱类型存储 , 和JavaScript使用方式无差别
Lua 声明变量通过 local
声明 , 采用 local 声明 , 主要意图是为了 避免全局变量的混乱和不必要的名称
local a = "lua";
Lua与JavaScript 区别
JavaScript : 作用在Web开发
Lua : 嵌入式开发/脚本应用
# 数据类型
Lua 常用数据类型 :
数据类型 | 说明 |
---|---|
nil | 代表 空/null (表达式中为false) |
boolean | 布尔值 true/false |
number | 浮点数 |
string | 字符串 (用 单引号/双引号 包围) |
function | 函数(引用方式和 JavaScript 一致) |
userdata | 任意存储在变量中的C数据结构 |
table | 和JSON误差 , 但是又能像数组存储数据 |
提示
lua 虽然是使用了弱类型 , 但可以通过 type()
进行判断类型
基本应用 :
--- 基本应用方式
local bool = false;
local str1 = "Sans"
local str2 = 'sans';
local num = 2;
table
该类型有两种应用方式 , 它能是 Map , 又能是 数组 , 是个较为特殊的类型 , 如下应用方式
--- key 下标
local arr = {'java','javaScript','lua'};
--- map 键值对
local map = {name='Sans',age=20};
--- 类型 ".." 类似于 +
print('type(arr) => ', type(arr)); -- type(arr) => nil
print('type(map) => ', type(map)); -- type(map) => table
--- 类型访问
print('arr[1] = ', arr[1]); -- arr[1] = java
print("map['name'] = ", map['name']); -- map['name'] = Sans
print("map.age = ", map.age); -- map.age = 20
提示
table 数组形式 , 下标起始位置为1 , 并非以0开头为下标 !!!
# 循环
# while
local count = 0;
while( count < 10 )
do
print("count => ", count);
count = count + 1;
end
# for
map遍历
local map = {name='Sans',age=20};
for key,value in pairs(map) do
print(key, value);
end
数组遍历
local arr = {'java','javaScript','lua'};
for index,value in ipairs(arr) do
print(index, value);
end
提示
注意 数组和Map 方式是不同的 ! 数组(ipairs) / map (pairs)
# 逻辑语法
# 条件逻辑
-- if
if(true) then
print("if Test")
end
-- if-else
if(false) then
print("if Test")
else
print("if-else Test")
end
# 运算符
其他运算符 和 JavaScript 一样 , 以下 与 或 非 例外
与 或 非 运算符
操作符 | 对照 | 说明 |
---|---|---|
and | && | 两者满足 |
or | || | 任意一者满足 |
not | != | 非判断... |
local a = true;
local b = false;
-- and
print("a and b => ", a and b); -- a and b => false
-- or
print("a or b => ", a or b); -- a or b => true
-- not
print("not(a) => ", not(a)); -- not(a) => false
print("not(b) => ", not(b)); -- not(b) => true
其他运算符
操作符 | 说明 |
---|---|
.. | 字符串拼接 |
+ | 整型相加 |
# | 返回 String/table 长度 |
-- 整型相加
local a = "12" + 2;
print(a); -- 14.0
print(type(a)); -- number
local a2 = "12" + "2";
print(a2); -- 14.0
print(type(a2)); -- number
-- 字符串拼接
local str = "12" .. 2;
print(str); -- 122
print(type(str)); -- string
local str2 = 12 .. 2;
print(str2); -- 122
print(type(str2)); -- string
-- # 长度获取
local s = "Sans";
local arr = {'java','javaScript','lua'};
local map = {name='Sans',age=20};
print(#s); -- 4
print(#arr); -- 3
print(#map); -- 0
++/..
很明显 Lua脚本是有 相加和拼接 区分 , 哪怕是整型的 字符串和字符串 相加 , 结果仍然是 相加后的结果 , 且类型还是 number类型
# 函数
function 函数名( argument1, argument2..., argumentn)
-- 函数体
return 返回值
end
# 面向对象
和Java有很多相似之处
o1 = { id = 1, name = "zhangsan" }
-- 为定义函数 (方法)
o1.getId = function(obj)
return obj.id
end
-- 追加函数
-- 打印
print("o1 => ", o1.getId(o1))
# 继承
子类可以使用父类的方法和属性
father = { a = 1, b = 2 }
father.faSay = function()
print("father say")
end
son = { c = 3 }
son.sonSay = function()
print("son say")
end
-- 为自己添加索引
father.__index = father
setmetatable(son, father)
son.sonSay()
son.faSay()
print("son.a: ", son.a)
print("son.b: ", son.b)
# 实例化
对象拷贝地址的相同的 , 但可以通过实例化另建地址
-- 实例化
t1 = { id = 1, name = "lisi" }
t2 = t1
-- 此时t1和t2指向同一个地址,修改t1的值,t2的值也会改变
print("t1和t2的地址是否相同: ", t1 == t2)
-- 无参实例化 (可以理解为深拷贝)
t1.__index = t1
function t1:new()
t = {}
setmetatable(t, self)
return t
end
t3 = t1.new()
print("t1和t3的地址是否相同: ", t1 == t3)
print("t3.id: ", t3.id)
-- 有参实例化
function t1:new(obj)
t = obj or {}
setmetatable(t, self)
-- 内部索引(无需外部操作)
self.__index = self
return t
end
t4 = t1.new({ id = 12 })
print("t1和t4的地址是否相同: ", t1 == t4)
print("t4.id: ", t4.id)
# 成员私有化
-- 成员私有化
function newUser()
id = 1
function getId()
return id
end
return {
getId=getId
}
end
user = newUser()
print("user.id: ", user.id)
print("user.getId(): ", user.getId())
# 高级应用
# 协程
协程是种类似线程概念 , 实现多任务并发执行
Lua协程特点
- 协作式 . 多个线程彼此让出控制权 , 进行切换执行
- 轻量级 . 不需要过多的系统资源 , 每个协程仅有自己的栈、局部变量、空间等..
- 单线程 . 执行期间任何时刻都是单线程运作(一个协程执行) , 其他处于挂起状态
通过 oroutine
关键字 实现
-- 创建协程
-- 无参线程
co = coroutine.create(function()
print("co1执行")
-- 挂起等待
coroutine.yield()
print("co1执行结束")
end)
-- 有参线程
co2 = coroutine.create(function(a, b)
print("co2执行")
print("参数1: ", a)
-- 挂起等待
coroutine.yield(11, 22)
print("参数2: ", b)
print("co2执行结束")
end)
-- 有返回值线程 (无返回则为boolean,是否成功)
co3 = coroutine.create(function()
print("co3执行")
-- 支持多参数返回传递
coroutine.yield(11, "co3执行挂起")
print("co3执行结束")
end)
print("co1状态 => ", coroutine.status(co))
print("co2状态 => ", coroutine.status(co2))
print("co3状态 => ", coroutine.status(co3))
-- 执行
print("========= 执行1 =========")
isOk = coroutine.resume(co)
isOk2 = coroutine.resume(co2, 22, 33)
isOk3, res1, res2 = coroutine.resume(co3)
print("co1和co2和co3执行情况分别是: ", res, res2, res3)
print("co3返回值: ", res1, res2)
print("co1和co2和co3状态信息分别是: ", coroutine.status(co), coroutine.status(co2), coroutine.status(co3))
print("========= 执行2 =========")
res = coroutine.resume(co)
res2 = coroutine.resume(co2, 22, 33)
res3, res1, res2 = coroutine.resume(co3)
print("co1和co2和co3执行情况分别是: ", res, res2, res3)
print("co3返回值: ", res1, res2)
print("co1和co2和co3状态信息分别是: ", coroutine.status(co), coroutine.status(co2), coroutine.status(co3))
# 工具化
工具类类似
应用
local StringUtils2 = require("StringUtils")
print(StringUtils2.append("", " 1234 ", " 5678 "))
第一个参数跳过
工具
StringUtils = {}
-- 拼接
function StringUtils:append(str, str2)
print(str, str2)
str = str or ""
str2 = str2 or ""
return str .. str2
end
return StringUtils
目前基本用法 , 临时将就学习 Redis 附加的知识点 , 如果有其他问题 , 评论说明哈~