Learn Lua
Date: . Last updated: .
Lua使用
元表的使用场景
作为table的元表
通过为table设置元表可以在lua中实现面向对象编程
作为userdata的元表
通过对userdata和元表可以实现在lua中对c中的结构进行面向对象式的访问
Lua坑
-- function table
local t = { name = "lua" }
function func(tab)
tab.name = string.upper(tab.name) -- 改变t.name字段
tab = { name = "AUL"} -- 不影响t表
end
func(t); print(t.name) -- LUA
Lua踩坑记录 lua中table如何安全移除元素
Lua Lib
Lua Algorithm
local function binary_search(list, value, less_than)
less_than = less_than or function(a, b)
return a < b
end
local min, max = 1, #list
while min <= max do
local pivot = min + math.floor((max - min) / 2)
local element = list[pivot]
if less_than(value, element) then
max = pivot - 1
elseif less_than(element, value) then
min = pivot + 1
else -- Neither smaller nor larger => must be equal
-- Index if found
return pivot
end
end
-- Negative insertion index if not found
return -min
end
Lua 源码
C++ Lua
弱引用表
在Lua中,变量没有类型,它可以是任何东西,而值有类型
如果一个对象只有弱引用指向它,那么gc会自动回收该对象的内存并删除这些弱引用
弱引用表weak table的用途一般都是出于GC考虑的
函数
多返回值
可变参数
函数闭包 主要应用在嵌套函数和匿名函数
高阶函数 函数作参数;返回函数
闭包应用:
- 作为高阶函数的参数,比如像table.sort函数的参数
- 创建其他的函数的函数,即函数返回一个闭包(工厂)
- 闭包对于回调函数也非常有用。典型的例子就是界面上按钮的回调函数,这些函数代码逻辑可能是一模一样,只是回调函数参数不一样而已,即upvalue的值不一样而已。
- 创建一个安全的运行环境,即所谓的沙盒(sandbox)。当执行一些未受信任的代码时就需要一个安全的运行环境
- 实现迭代器,每个迭代器都需要在每次成功调用之间保持一些状态,这样才能知道它所在的位置及如何进到下一个位置
尾递归:
function factorial(n,total)
total = total or 1 -- default parameter
if(n == 1) then
return total
end
return factorial(n-1,n*total)
end
print(factorial(5)) -- 120
upvalue 实际指的是变量而不是值,这些变量可以在内部函数之间共享,即 upvalue 提供一种闭包之间共享数据的方法
深入理解Lua的闭包一:概念、应用和实现原理
lua成长笔记
字符串
正则
-- string.find, string.match, string.gmatch, string.gsub
-- . :表示任何字符
-- %a: 表示任何字母。
-- %c: 表示任何控制字符。
-- %d: 表示任何数字。
-- %g: 表示任何除空白符外的可打印字符。
-- %l: 表示所有小写字母。
-- %p: 表示所有标点符号。
-- %s: 表示所有空白字符。
-- %u: 表示所有大写字母。
-- %w: 表示所有字母及数字。
-- %x: 表示所有 16 进制数字符号。
-- (这里的 x 是任意非字母或数字的字符) 表示字符 x。 这是对魔法字符转义的标准方法。 所有非字母或数字的字符 (包括所有标点,也包括非魔法字符) 都可以用前置一个 '%' 放在模式串中表示自身
-- (). % + - * ? [ ^ $: 特殊字符,需要用%转义
-- +:匹配前一字符 1 次或多次,最长匹配
-- *:匹配前一字符 0 次或多次,最长匹配
-- -: 匹配前一字符 0 次或多次,最短匹配
-- ?: 匹配前一字符 0 次或 1次
截取 -- string.sub (s, i [, j])
str = "https://www.lua.org/"
string.sub( str, 2, 3)
string.sub( str, -4,-2)
替换 -- string.gsub (s, pattern, repl [, n])
str = "https://www.lua.org/"
string.gsub( str, "w", "m") -- https://mmm.lua.org/ 3
string.gsub( str, "w", "m",2) -- https://mmw.lua.org/ 2
查找 -- string.find (s, pattern [, init [, plain]]) plain->true 关闭正则
str = "https://www.lua.org/"
string.find( str, "lua") -- 13 15
string.find( str, "lua",15) -- nil
匹配 -- string.match (s, pattern [, init])
str = "https://www.lua.org/"
string.match( str, "%a+") -- https
string.find( str, "%a+",13) -- lua
迭代匹配 -- string.gmatch (s, pattern [, init])
str = "https://www.lua.org/"
local words = {}
for w in string.gmatch(str,"%a+") do
table.insert(words,w)
end
print(table.concat(words," ")) -- https www lua org
格式化 -- string.format (formatstring, ···)
string.format("age = %d",10)
重复 -- string.rep (s, n [, sep])
str = "https://www.lua.org/"
string.rep(str,2," ") -- https://www.lua.org/ https://www.lua.org/
反转 -- string.reverse (s)
str = "https://www.lua.org/"
string.reverse(str) -- /gro.aul.www//:sptth
WIP -- string.pack (fmt, v1, v2, ···)
-- string.packsize (fmt)
-- string.unpack (fmt, s [, pos])
Lua 字符串操作
表
拼接
-- table.concat (list [, sep [, i [, j]]])
tab = {"lua","table","string"}
table.concat(tab," ",2,3) -- table string
插入 -- table.insert (list, [pos,] value) 数组能用, 字典不行
tab = {"lua","table","string"}
table.insert(tab,"function")
table.concat(tab," ") -- lua table string function
删除 -- table.remove (list [, pos]) 数组能用, 字典不行
tab = {"lua","table","string"}
table.remove(tab) -- string
table.concat(tab," ") -- lua table
移动 -- table.move (a1, f, e, t [,a2])
tab1 = {"lua","table","string"}
tab2 = {128}
table.move(tab1,2,3,2,tab2) -- table: 000001bd5dec0e10
table.concat(tab2," ") -- 128 table string
排序 -- table.sort (list [, comp])
tab = {"lua","table","string"}
table.sort(tab)
table.concat(tab," ") -- lua string table
时间
日期
-- os.date ([format [, time]]) --返回本地化的时间字符串
os.date() -- 05/08/23 23:52:29
-- format
-- %a 一个星期中天数的简写(如:Wed)
-- %A 一个星期中天数的全称(如: Wednesday)
-- %b 月份的简写(如: Sep)
-- %B 月份的全称(如:September)
-- %c 日期和时间(如: 08/22/2017 10:50:05)
-- %d 一个月中的第几天(22) [0 - 31]
-- %H 24小时中的小时数(15) [0 - 23]
-- %I 12小时中的小时数(8)[1 - 12]
-- %j 一年中的第几天(259)[1 - 366]
-- %M 分钟数 (48) [0 - 59]
-- %m 月份数 (09) [1 - 12]
-- %p "上午(am)"或"下午(pm)" (如: pm)
-- %S 秒数(10) [0 - 59]
-- %w 一个星期中的第几天(3) [0 - 6 周天-周六]
-- %x 日期(如:08/22/17)
-- %X 时间(如:10:50:05)
-- %y 两位数的年份(17) [00 - 99]
-- %Y 完整的年份(2023)
-- %% 字符'%'
-- *t 返回表 hour min wday day month year sec yday isdst
时间戳 -- os.time ([table])
os.time() -- 1683561264
os.time({year=2023, month = 5, day=8, hour=23, min=57,sec=30,isdst=false}) -- 1683561450
-- os.difftime (t2, t1)
t1 = os.time()
t2 = os.time()
os.difftime(t2,t1) -- 5.0
Lua中时间函数的用法整理
随机数
-- math.randomseed ([x [, y]])
-- math.random ([m [, n]])
math.randomseed(tostring(os.time()):reverse():sub(1,7))
for i = 1, 5 do
print(math.random(1,100))
end
-- math.random() --> (0,1)
-- math.random(n) --> (0,n)
-- math.random(m,n) --> (m,n)
数学库
-- math.abs (x) -- 取绝对值
math.abs(-2023.511) -- 2023.511
-- math.ceil (x) -- 向上取整
math.ceil(2.5) -- 3
-- math.floor (x) -- 向下取整
math.floor(2.5) -- 2
-- math.fmod (x, y) -- 取余
math.fmod(-2,3) -- -2
-- math.modf (x) --取整数部分和小数部分
math.modf(-16.78) -- -16 -0.78
-- + - * / 加减乘除
-- // % ^ 整除 取余 幂运算
Lua中的数学库 数学库
lua取模运算math.fmod和% 的区别
"Success is the ability to go from one failure to another without losing enthusiasm." --Winston Churchill