From 637317e7facebac8a9ace151f24d4339ebc4fdbd Mon Sep 17 00:00:00 2001 From: goer <1138871845@qq.com> Date: Mon, 29 Jun 2020 09:24:44 +0800 Subject: [PATCH] create lua.lua usages of lua --- languages/lua.lua | 409 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 409 insertions(+) create mode 100644 languages/lua.lua diff --git a/languages/lua.lua b/languages/lua.lua new file mode 100644 index 0000000..6ff6226 --- /dev/null +++ b/languages/lua.lua @@ -0,0 +1,409 @@ + -------------------------------------------------------------------------------- + -- Lua CHEATSHEET (中文速查表) - by weizhixiangcoder (created on 2020/06/20) + -- Version: 1 + -- https://github.com/skywind3000/awesome-cheatsheets + -------------------------------------------------------------------------------- + + +--------------------------------------------------------------------------------- +--[[ + Lua 特性: + 轻量级:源码2.5万行左右C代码, 方便嵌入进宿主语言(C/C++) + 可扩展:提供了易于使用的扩展接口和机制, 使用宿主语言提供的功能 + 高效性:运行最快的脚本语言之一 + 可移植:跨平台 + 入门书籍《lua程序设计》 + 推荐:云风翻译的《Lua 5.3参考手册》 + http://cloudwu.github.io/lua53doc/manual.html + 源码: + http://www.lua.org/ftp/ +--]] +--------------------------------------------------------------------------------- + + +--------------------------------------------------------------------------------- +--[[ + 变量: 作为动态类型语言,变量本身没有类型, 赋值决定某一时刻变量的类型。私有静态 + 变量带local, 公有静态变量不带local。 + 数据类型: + nil 为空,无效值,在条件判断中表示false + boolean 包含两个值:false和true + number 表示双精度类型的实浮点数 + string 字符串由一对双引号或单引号来表示 + function 由 C 或 Lua 编写的函数 + table Lua 中的表(table)其实是一个"关联数组"(associative + arrays),数组的索引可以是数字、字符串或表类型 + thread 协程 + userdata 存储在变量中的C数据结构 +--]] +--------------------------------------------------------------------------------- +print(type(signal)) --nil + +signal = true +print(type(signal)) --boolean + +signal = 1454 +print(type(signal)) --number + +signal = "UnionTech" +print(type(signal)) --string + +signal = function() + print(type(signal)) +end +print(type(signal)) --function + +signal = {} +print(type(signal)) --table + +signal = coroutine.create(function() + print(type(signal)) +end) +print(type(signal)) --coroutine + + + +--------------------------------------------------------------------------------- +--[[ + 流程控制:if...elseif...else、 while、 for +--]] +--------------------------------------------------------------------------------- +--if...else +ty_signal = type(signal) +if ty_signal == "coroutine" then + print("signal type is coroutine") +elseif ty_signal == "table" then + print("signal type is table") +else + print("signal type is other") +end + +--while +ut_companys = {"beijing company", "shanghai company", "nanjing company", "wuxi company", "guangzhou company", "yunfu company", "wuhan company", "chengdu company", "xian company"} +count = 0 +while count <= #ut_companys +do + count = count + 1 + print("ut_companys[", count, "] is ", ut_companys[count]) +end + +--for +for i=#ut_companys, 1, -2 do --以2为步长反向遍历 + print("num: ", i, "company: ", ut_companys[i]) +end + + +--------------------------------------------------------------------------------- +--[[ + table: 表作为Lua唯一自带的数据结构, 使用简单方便, 兼具数组和Map作为容器的 + 功能,通过表可以很容易组成常见的数据结构, 如栈、队列、链表、集合,用for循环 + 很容易迭代遍历表数据。 +--]] +--------------------------------------------------------------------------------- +--table当数组用,下标从1开始 +for i, c in ipairs(ut_companys) do + print(string.format("1 UnionTech company: %d %s", i, c)) +end + +table.sort(ut_companys) +for i=#ut_companys, 1, -1 do + print(string.format("2 UnionTech company: %d %s", i, ut_companys[i])) +end + +--table当hash map用 +ut_cptypes = {} + +ut_cptypes["adapter"] = {"beijing company", "wuhan company", "guangzhou company"} +ut_cptypes["developer"] = {"beijing company", "wuhan company", "nanjing company", "chengdu company", "xian company", "guangzhou company"} +ut_cptypes["general"] = {"beijing company"} + +for ty, cps in pairs(ut_cptypes) do + for i, cp in ipairs(cps) do + print(string.format("3 UnionTech companys: type:%s identifier:%s company:%s", ty, i, cp)) + end +end + + +--------------------------------------------------------------------------------- +--[[ + 函数:在Lua中函数也是第一类型值, 可赋值给变量, 也可以在函数体内定义并使用函数,或者 + 是直接使用匿名匿名函数。 +--]] +--------------------------------------------------------------------------------- +--多重返回值 +ut_types = {"adapter", "developer", "general"} +function company_types(cp, cptypes) + local adpt, dvlp, genl = nil, nil, nil + for i, ty in ipairs(ut_types) do + for _, _cp in ipairs(cptypes[ty]) do + if _cp == cp then + if i == 1 then + adpt = true + elseif i == 2 then + dvlp = true + elseif i == 3 then + genl = true + end + break + end + end + end + return adpt, dvlp, genl +end + +cp = "wuhan company" +types = {company_types(cp, ut_cptypes)} + +for i, ty in ipairs(types) do + if ty then + print(string.format("%s is %s", cp, ut_types[i])) + end +end + +--变参 +function printf(str, ...) + print(string.format(str, ...)) +end + +function add_companys(...) + local newcps = {...} + local num = #newcps + for _, cp in ipairs(newcps) do + table.insert(ut_companys, cp) + end + return ut_companys, num +end + +_, _ = add_companys("changsha company", "zhengzhou company", "hefei company") +for i=1, #ut_companys do + --print(string.format("4 UnionTech company: %d %s", i, ut_companys[i])) + printf("4 UnionTech company: %d %s", i, ut_companys[i]) +end + +--闭包 +function all_companys(cps) + local companys, n = {}, 0 + for _, v in ipairs(cps) do + table.insert(companys, v) + end + return function() + n = n + 1 + if n > #companys then + return "" + else + return companys[n] + end + end +end + +get_company = all_companys(ut_companys) +while true +do + cp = get_company() + if cp == "" then + break + else + printf("get company: %s", cp) + end +end + + +--------------------------------------------------------------------------------- +--[[ + 协程(coroutine):Lua协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局 + 部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西。 +--]] +--------------------------------------------------------------------------------- +function foo (a) + print("foo 函数输出", a) + return coroutine.yield(2 * a) -- 返回 2*a 的值 +end + +co = coroutine.create(function (a , b) + print("第一次协同程序执行输出", a, b) -- co-body 1 10 + local r = foo(a + 1) + + print("第二次协同程序执行输出", r) + local r, s = coroutine.yield(a + b, a - b) -- a,b的值为第一次调用协同程序时传入 + + print("第三次协同程序执行输出", r, s) + return b, "结束协同程序" -- b的值为第二次调用协同程序时传入 +end) + +print("main", coroutine.resume(co, 1, 10)) -- true, 4 +print("main", coroutine.resume(co, "r")) -- true 11 -9 +print("main", coroutine.resume(co, "x", "y")) -- true 10 end +print("main", coroutine.resume(co, "x", "y")) -- cannot resume dead coroutine +--resume将主协程数据传入次协程, yield将次协程中数据传回主协程 + + +--------------------------------------------------------------------------------- +--[[ + 元表(Metatable):本质上来说就是存放元方法的表结构, 通过元表实现对表中数据和行为 + 的改变。 + Lua 查找一个表元素时的规则,其实就是如下 3 个步骤: + 1.在表中查找,如果找到,返回该元素,找不到则继续 + 2.判断该表是否有元表,如果没有元表,返回 nil,有元表则继续。 + 3.判断元表有没有 __index 方法,如果 __index 方法为 nil,则返回 nil;如果 + __index 方法是一个表,则重复 1、2、3;如果 __index 方法是一个函数,则返 + 回该函数的返回值 + +--]] +--------------------------------------------------------------------------------- +father = { + colourofskin = "yellow", + weight = 70, + work = "programming", + otherwork = function() + print "do housework" + end +} +father.__index = father + +son = { + weight = 50, + like = "basketball" +} + +setmetatable(son, father) +printf("weight:%d like:%s work:%s colourofskin:%s ", son.weight, son.like, son.work, son.colourofskin) +son.otherwork() + + +--------------------------------------------------------------------------------- +--[[ + 面向对象:因为lua本身不是面向对象的语言, 在lua中, 通过table和function来模拟一个对象, + 用metatable来模拟面向对象中的继承,但是在使用的时候需要考虑lua作为脚本语言, 变量的类型随 + 所赋值类型而改变。 +--]] +--------------------------------------------------------------------------------- +--父类 +rect = { + area = 0, + length = 0, + width = 0, +} + +function rect:getArea() + if self.area == 0 then + self.area = self.length * self.width + end + + return self.area +end + +function rect:getLength() + return self.length +end + +function rect:new(leng, wid) + self.length = leng + self.width = wid + return self +end + +--子类 +cuboid = { + volume = 0, + height = 0, +} + +function cuboid:getVolume() + if self.volume == 0 then + self.volume = self.height * self:getArea() + end + return self.volume +end + +function cuboid:new(_rect, _height) + setmetatable(self, _rect) + _rect.__index = _rect + self.height = _height + return self +end + +rect1 = rect:new(5, 10) +print("rect1 rectangle:", rect1:getArea()) + +cuboid1 = cuboid:new(rect1, 2) +print("cuboid1 volume: ", cuboid1:getVolume()) +print("cuboid1 rectangle: ", cuboid1:getArea()) --子类调用父类方法getArea +print("cuboid1 length function: ", cuboid1:getLength()) --子类调用父类方法getLength +print("cuboid1 length variable: ", cuboid1.length) --子类使用父类变量length + +--重写子类接口getArea, lua中没有重载 +function cuboid:getArea() + return 2 * (self.height * self.length + self.height * self.width + self.length * self.width) +end + +cuboid2 = cuboid:new(rect1, 2) +print("cuboid2 function: getArea: ", cuboid2:getArea()) --调用子类重写的方法getArea +print("cuboid2 base function: getArea: ", getmetatable(cuboid2):getArea()) --显示调用父类方法getArea + + +--------------------------------------------------------------------------------- +--[[ + 模块与C包: 模块类似封装库, 有利于代码复用, 降低耦合, 提供被调用的API。 + ---------------------------------------------------------------------- + -- 文件名为 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 + + 在其他模块中调用module模块: + local m = require("module") + print(m.constant) + ---------------------------------------------------------------------- + 与Lua中写包不同,C包在使用以前必须首先加载并连接,在大多数系统中最容易的实现方式 + 是通过动态连接库机制。Lua在一个叫loadlib的函数内提供了所有的动态连接的功能。 + + ---------------------------------------------------------------------- +--]] +--------------------------------------------------------------------------------- + + +--------------------------------------------------------------------------------- +--[[ + lua标准库: 标准库中接口可直接使用不需要require + 常用标准库: + math 数学计算 + table 表结构数据处理 + string 字符串处理 + os 系统库函数 + io 文件读写 + coroutine 协程库 + debug 调式器 +--]] +--------------------------------------------------------------------------------- + + +--------------------------------------------------------------------------------- +--[[ + lua虚拟机:脚本语言没有像编译型语言那样直接编译为机器能识别的机器代码,这意味着 + 解释性脚本语言与编译型语言的区别:由于每个脚本语言都有自己的一套字节码,与具体的 + 硬件平台无关,所以无需修改脚本代码,就能运行在各个平台上。硬件、软件平台的差异都 + 由语言自身的虚拟机解决。由于脚本语言的字节码需要由虚拟机执行,而不像机器代码那样 + 能够直接执行,所以运行速度比编译型语言差不少。有了虚拟机这个中间层,同样的代码可 + 以不经修改就运行在不同的操作系统、硬件平台上。Java、Python都是基于虚拟机的编程语 + 言,Lua同样也是这样。 + + +--]] +--------------------------------------------------------------------------------- + + + + +--可在命令行lua lua.lua运行本脚本