lua.lua 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. --------------------------------------------------------------------------------
  2. -- Lua CHEATSHEET (中文速查表) - by weizhixiangcoder (created on 2020/06/20)
  3. -- Version: 1
  4. -- https://github.com/skywind3000/awesome-cheatsheets
  5. --------------------------------------------------------------------------------
  6. ---------------------------------------------------------------------------------
  7. --[[
  8. Lua 特性:
  9. 轻量级:源码2.5万行左右C代码, 方便嵌入进宿主语言(C/C++)
  10. 可扩展:提供了易于使用的扩展接口和机制, 使用宿主语言提供的功能
  11. 高效性:运行最快的脚本语言之一
  12. 可移植:跨平台
  13. 入门书籍《lua程序设计》
  14. 推荐:云风翻译的《Lua 5.3参考手册》
  15. http://cloudwu.github.io/lua53doc/manual.html
  16. 源码:
  17. http://www.lua.org/ftp/
  18. --]]
  19. ---------------------------------------------------------------------------------
  20. ---------------------------------------------------------------------------------
  21. --[[
  22. 变量: 作为动态类型语言,变量本身没有类型, 赋值决定某一时刻变量的类型。私有静态
  23. 变量带local, 公有静态变量不带local。
  24. 数据类型:
  25. nil 为空,无效值,在条件判断中表示false
  26. boolean 包含两个值:false和true
  27. number 表示双精度类型的实浮点数
  28. string 字符串由一对双引号或单引号来表示
  29. function 由 C 或 Lua 编写的函数
  30. table Lua 中的表(table)其实是一个"关联数组"(associative
  31. arrays),数组的索引可以是数字、字符串或表类型
  32. thread 协程
  33. userdata 存储在变量中的C数据结构
  34. --]]
  35. ---------------------------------------------------------------------------------
  36. print(type(signal)) --nil
  37. signal = true
  38. print(type(signal)) --boolean
  39. signal = 1454
  40. print(type(signal)) --number
  41. signal = "UnionTech"
  42. print(type(signal)) --string
  43. signal = function()
  44. print(type(signal))
  45. end
  46. print(type(signal)) --function
  47. signal = {}
  48. print(type(signal)) --table
  49. signal = coroutine.create(function()
  50. print(type(signal))
  51. end)
  52. print(type(signal)) --coroutine
  53. ---------------------------------------------------------------------------------
  54. --[[
  55. 流程控制:if...elseif...else、 while、 for
  56. --]]
  57. ---------------------------------------------------------------------------------
  58. --if...else
  59. ty_signal = type(signal)
  60. if ty_signal == "coroutine" then
  61. print("signal type is coroutine")
  62. elseif ty_signal == "table" then
  63. print("signal type is table")
  64. else
  65. print("signal type is other")
  66. end
  67. --while
  68. ut_companys = {"beijing company", "shanghai company", "nanjing company", "wuxi company", "guangzhou company", "yunfu company", "wuhan company", "chengdu company", "xian company"}
  69. count = 0
  70. while count <= #ut_companys
  71. do
  72. count = count + 1
  73. print("ut_companys[", count, "] is ", ut_companys[count])
  74. end
  75. --for
  76. for i=#ut_companys, 1, -2 do --以2为步长反向遍历
  77. print("num: ", i, "company: ", ut_companys[i])
  78. end
  79. ---------------------------------------------------------------------------------
  80. --[[
  81. table: 表作为Lua唯一自带的数据结构, 使用简单方便, 兼具数组和Map作为容器的
  82. 功能,通过表可以很容易组成常见的数据结构, 如栈、队列、链表、集合,用for循环
  83. 很容易迭代遍历表数据。
  84. --]]
  85. ---------------------------------------------------------------------------------
  86. --table当数组用,下标从1开始
  87. for i, c in ipairs(ut_companys) do
  88. print(string.format("1 UnionTech company: %d %s", i, c))
  89. end
  90. table.sort(ut_companys)
  91. for i=#ut_companys, 1, -1 do
  92. print(string.format("2 UnionTech company: %d %s", i, ut_companys[i]))
  93. end
  94. --table当hash map用
  95. ut_cptypes = {}
  96. ut_cptypes["adapter"] = {"beijing company", "wuhan company", "guangzhou company"}
  97. ut_cptypes["developer"] = {"beijing company", "wuhan company", "nanjing company", "chengdu company", "xian company", "guangzhou company"}
  98. ut_cptypes["general"] = {"beijing company"}
  99. for ty, cps in pairs(ut_cptypes) do
  100. for i, cp in ipairs(cps) do
  101. print(string.format("3 UnionTech companys: type:%s identifier:%s company:%s", ty, i, cp))
  102. end
  103. end
  104. ---------------------------------------------------------------------------------
  105. --[[
  106. 函数:在Lua中函数也是第一类型值, 可赋值给变量, 也可以在函数体内定义并使用函数,或者
  107. 是直接使用匿名匿名函数。
  108. --]]
  109. ---------------------------------------------------------------------------------
  110. --多重返回值
  111. ut_types = {"adapter", "developer", "general"}
  112. function company_types(cp, cptypes)
  113. local adpt, dvlp, genl = nil, nil, nil
  114. for i, ty in ipairs(ut_types) do
  115. for _, _cp in ipairs(cptypes[ty]) do
  116. if _cp == cp then
  117. if i == 1 then
  118. adpt = true
  119. elseif i == 2 then
  120. dvlp = true
  121. elseif i == 3 then
  122. genl = true
  123. end
  124. break
  125. end
  126. end
  127. end
  128. return adpt, dvlp, genl
  129. end
  130. cp = "wuhan company"
  131. types = {company_types(cp, ut_cptypes)}
  132. for i, ty in ipairs(types) do
  133. if ty then
  134. print(string.format("%s is %s", cp, ut_types[i]))
  135. end
  136. end
  137. --变参
  138. function printf(str, ...)
  139. print(string.format(str, ...))
  140. end
  141. function add_companys(...)
  142. local newcps = {...}
  143. local num = #newcps
  144. for _, cp in ipairs(newcps) do
  145. table.insert(ut_companys, cp)
  146. end
  147. return ut_companys, num
  148. end
  149. _, _ = add_companys("changsha company", "zhengzhou company", "hefei company")
  150. for i=1, #ut_companys do
  151. --print(string.format("4 UnionTech company: %d %s", i, ut_companys[i]))
  152. printf("4 UnionTech company: %d %s", i, ut_companys[i])
  153. end
  154. --闭包
  155. function all_companys(cps)
  156. local companys, n = {}, 0
  157. for _, v in ipairs(cps) do
  158. table.insert(companys, v)
  159. end
  160. return function()
  161. n = n + 1
  162. if n > #companys then
  163. return ""
  164. else
  165. return companys[n]
  166. end
  167. end
  168. end
  169. get_company = all_companys(ut_companys)
  170. while true
  171. do
  172. cp = get_company()
  173. if cp == "" then
  174. break
  175. else
  176. printf("get company: %s", cp)
  177. end
  178. end
  179. ---------------------------------------------------------------------------------
  180. --[[
  181. 协程(coroutine):Lua协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局
  182. 部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西。
  183. --]]
  184. ---------------------------------------------------------------------------------
  185. function foo (a)
  186. print("foo 函数输出", a)
  187. return coroutine.yield(2 * a) -- 返回 2*a 的值
  188. end
  189. co = coroutine.create(function (a , b)
  190. print("第一次协同程序执行输出", a, b) -- co-body 1 10
  191. local r = foo(a + 1)
  192. print("第二次协同程序执行输出", r)
  193. local r, s = coroutine.yield(a + b, a - b) -- a,b的值为第一次调用协同程序时传入
  194. print("第三次协同程序执行输出", r, s)
  195. return b, "结束协同程序" -- b的值为第二次调用协同程序时传入
  196. end)
  197. print("main", coroutine.resume(co, 1, 10)) -- true, 4
  198. print("main", coroutine.resume(co, "r")) -- true 11 -9
  199. print("main", coroutine.resume(co, "x", "y")) -- true 10 end
  200. print("main", coroutine.resume(co, "x", "y")) -- cannot resume dead coroutine
  201. --resume将主协程数据传入次协程, yield将次协程中数据传回主协程
  202. ---------------------------------------------------------------------------------
  203. --[[
  204. 元表(Metatable):本质上来说就是存放元方法的表结构, 通过元表实现对表中数据和行为
  205. 的改变。
  206. Lua 查找一个表元素时的规则,其实就是如下 3 个步骤:
  207. 1.在表中查找,如果找到,返回该元素,找不到则继续
  208. 2.判断该表是否有元表,如果没有元表,返回 nil,有元表则继续。
  209. 3.判断元表有没有 __index 方法,如果 __index 方法为 nil,则返回 nil;如果
  210. __index 方法是一个表,则重复 1、2、3;如果 __index 方法是一个函数,则返
  211. 回该函数的返回值
  212. --]]
  213. ---------------------------------------------------------------------------------
  214. father = {
  215. colourofskin = "yellow",
  216. weight = 70,
  217. work = "programming",
  218. otherwork = function()
  219. print "do housework"
  220. end
  221. }
  222. father.__index = father
  223. son = {
  224. weight = 50,
  225. like = "basketball"
  226. }
  227. setmetatable(son, father)
  228. printf("weight:%d like:%s work:%s colourofskin:%s ", son.weight, son.like, son.work, son.colourofskin)
  229. son.otherwork()
  230. ---------------------------------------------------------------------------------
  231. --[[
  232. 面向对象:因为lua本身不是面向对象的语言, 在lua中, 通过table和function来模拟一个对象,
  233. 用metatable来模拟面向对象中的继承,但是在使用的时候需要考虑lua作为脚本语言, 变量的类型随
  234. 所赋值类型而改变。
  235. --]]
  236. ---------------------------------------------------------------------------------
  237. --父类
  238. rect = {
  239. area = 0,
  240. length = 0,
  241. width = 0,
  242. }
  243. function rect:getArea()
  244. if self.area == 0 then
  245. self.area = self.length * self.width
  246. end
  247. return self.area
  248. end
  249. function rect:getLength()
  250. return self.length
  251. end
  252. function rect:new(leng, wid)
  253. self.length = leng
  254. self.width = wid
  255. return self
  256. end
  257. --子类
  258. cuboid = {
  259. volume = 0,
  260. height = 0,
  261. }
  262. function cuboid:getVolume()
  263. if self.volume == 0 then
  264. self.volume = self.height * self:getArea()
  265. end
  266. return self.volume
  267. end
  268. function cuboid:new(_rect, _height)
  269. setmetatable(self, _rect)
  270. _rect.__index = _rect
  271. self.height = _height
  272. return self
  273. end
  274. rect1 = rect:new(5, 10)
  275. print("rect1 rectangle:", rect1:getArea())
  276. cuboid1 = cuboid:new(rect1, 2)
  277. print("cuboid1 volume: ", cuboid1:getVolume())
  278. print("cuboid1 rectangle: ", cuboid1:getArea()) --子类调用父类方法getArea
  279. print("cuboid1 length function: ", cuboid1:getLength()) --子类调用父类方法getLength
  280. print("cuboid1 length variable: ", cuboid1.length) --子类使用父类变量length
  281. --重写子类接口getArea, lua中没有重载
  282. function cuboid:getArea()
  283. return 2 * (self.height * self.length + self.height * self.width + self.length * self.width)
  284. end
  285. cuboid2 = cuboid:new(rect1, 2)
  286. print("cuboid2 function: getArea: ", cuboid2:getArea()) --调用子类重写的方法getArea
  287. print("cuboid2 base function: getArea: ", getmetatable(cuboid2):getArea()) --显示调用父类方法getArea
  288. ---------------------------------------------------------------------------------
  289. --[[
  290. 模块与C包: 模块类似封装库, 有利于代码复用, 降低耦合, 提供被调用的API。
  291. ----------------------------------------------------------------------
  292. -- 文件名为 module.lua, 定义一个名为 module 的模块
  293. module = {}
  294. module.constant = "这是一个常量"
  295. function module.func1()
  296. io.write("这是一个公有函数!\n")
  297. end
  298. local function func2()
  299. print("这是一个私有函数!")
  300. end
  301. function module.func3()
  302. func2()
  303. end
  304. return module
  305. 在其他模块中调用module模块:
  306. local m = require("module")
  307. print(m.constant)
  308. ----------------------------------------------------------------------
  309. 与Lua中写包不同,C包在使用以前必须首先加载并连接,在大多数系统中最容易的实现方式
  310. 是通过动态连接库机制。Lua在一个叫loadlib的函数内提供了所有的动态连接的功能。
  311. ----------------------------------------------------------------------
  312. --]]
  313. ---------------------------------------------------------------------------------
  314. ---------------------------------------------------------------------------------
  315. --[[
  316. lua标准库: 标准库中接口可直接使用不需要require
  317. 常用标准库:
  318. math 数学计算
  319. table 表结构数据处理
  320. string 字符串处理
  321. os 系统库函数
  322. io 文件读写
  323. coroutine 协程库
  324. debug 调式器
  325. --]]
  326. ---------------------------------------------------------------------------------
  327. ---------------------------------------------------------------------------------
  328. --[[
  329. lua虚拟机:脚本语言没有像编译型语言那样直接编译为机器能识别的机器代码,这意味着
  330. 解释性脚本语言与编译型语言的区别:由于每个脚本语言都有自己的一套字节码,与具体的
  331. 硬件平台无关,所以无需修改脚本代码,就能运行在各个平台上。硬件、软件平台的差异都
  332. 由语言自身的虚拟机解决。由于脚本语言的字节码需要由虚拟机执行,而不像机器代码那样
  333. 能够直接执行,所以运行速度比编译型语言差不少。有了虚拟机这个中间层,同样的代码可
  334. 以不经修改就运行在不同的操作系统、硬件平台上。Java、Python都是基于虚拟机的编程语
  335. 言,Lua同样也是这样。
  336. --]]
  337. ---------------------------------------------------------------------------------
  338. --可在命令行lua lua.lua运行本脚本