
lua教程
https://moonbingbing.gitbooks.io/openresty-best-practices/content/lua/class.html
lua最核心的就是table,table中的变量、函数就构成了一个对象,可以理解成,一个table就等同于面向对象编程。
同时一个table,就可以成为一个module被别的lua代码导入,使用:
require("module")就可以导入module.lua文件中定义的table作为一个模块。lua还会把这个模块的table声明为一个全局变量,这样在require之后,就可以直接使用table的名字来访问table里的函数或者变量了。
require的返回值
require “xxx” 某个模块后
1.如果该模块自身有返回值,且模块加载成功,那么require 的返回值就是该模块的返回值
2.如果模块没有返回值,如果require加载模块成功,就返回ture
3.require 内部将返回值储存在:package.loaded表中。
(即:package.loaded[xxx]中)
4.例子
(1)main.lua
x = require "test"
function Call()
x.show()
end
(2)test.lua
local tb = {}
function tb.show()
print("it is ok")
end
return tb
(3)testLua.cpp
int _tmain(int argc, _TCHAR* argv[])
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
luaL_dofile(L,"Lua//main.lua");
lua_getglobal(L,"Call");
lua_pcall(L,0,0,0);
return 0;
}
https://www.jianshu.com/p/d727825816ee
2、--是注释符
3、成员访问符
有句号和冒号两种
通过句号调用函数时,不会将self作为参数传入给函数,所以如果函数需要用self,则会报错。
而冒号调用函数时,会将self作为参数传入。
4、双点是字符串拼接
local a = "hello".."world"
上面的a就是helloworld,等价于别的语言的字符串+运算。
5、and or
逻辑运算时就是普通的与/或逻辑,在lua中,数值为0为true而不是false,这一点与其他语言不同
但是lua的and和or会返回操作数
- and 返回第一个不为真的操作数,如果都为真,则返回最后一个操作数
a = 0 and 1
a为1
a = nil and 1
a为nil
- or 返回第一个为真的操作数,如果都不为真,则返回最后一个操作数
a = 0 or 1
a 为0
a = nil or false
a 为false
6、ipairs pairs
两个都是用来迭代遍历集合和table的,但有不同
ipairs是将被迭代的对象当成数组一样,会从下标1开始遍历,一旦发现下一个下标的元素不存在,就会结束迭代。
local tabFiles = {
[1] = "test2",
[6] = "test3",
[4] = "test1"
}
for k, v in ipairs(tabFiles) do --输出"test2",在key等于2处断开
print(k, v)
end
local tabFiles = {
[2] = "test2",
[6] = "test3",
[4] = "test1"
}
for k, v in ipairs(tabFiles) do --[[什么都没输出,为什么?因为控制变量初始值是按升序来遍历的,当key为1时,value为nil,此时便停止了遍历, 所有什么结果都没输出]]--
print(k, v)
end
而pairs就是普遍意义上的遍历所有的元素
local tabFiles = {
[2] = "test2",
[6] = "test3",
[4] = "test1"
}
for k, v in pairs(tabFiles) do --输出2 test2, 6 test3, 4 test1
print(k, v)
end
local tabFiles = {"alpha", "beta", [3] = "no", ["two"] = "yes"} for i,v in ipairs(tabFiles ) do --输出前三个 备注:因为第四个key不是整数
print( tabFiles [i] )
end
for i,v in pairs(tabFiles ) do --全部输出
print( tabFiles [i] )
end
https://www.runoob.com/note/11315
7、变量类型
Lua 变量有三种类型:全局变量、局部变量、表中的域。
Lua 中的变量全是全局变量,哪怕是语句块或是函数里,除非用 local 显式声明为局部变量。
局部变量的作用域为从声明位置开始到所在语句块结束。
变量的默认值均为 nil。
8、下标从1开始
9、table

10、local xxx do xxx end

上面的例子没有截取完整,下面的代码就是函数的定义和do语句块的结束。
我们可以看到有两处声明了同名的对象fill_node_info,在lua中没有使用local前缀的都是全局对象,但是这个代码中里面的fill_node_info并不是一个全局对象,这其实是lua 的语法特性:
function fill_node_info() 是等价于 fill_node_info=function()的,所以里面的fill_node_info只是对外面的local fill_node_info的重新赋值,这时候fill_node_info就变成了一个函数,也是局部对象;而这里的do的作用就是保护语句块中的一些数据而已。
do end等价于c++的{}作用域。
11、io.write
io.write在没有指定文件时,等同于print

12、执行lua脚本
和python类似,命令行执行lua进入console
lua code_file.lua 运行代码
13、判断lua的table是否为空
local mytable = {}
local mytable2 = {333,"hello",666}
if next(mytable) == nil then
print("mytable is true")
else
print("mytable is false")
end
if next(mytable2) == nil then
print("mytable2 is true")
else
print("mytable2 is false")
end
或者
local mytable = {}
if #mytable == 0 then
print("empty table")
end
14、字符串日前转时间戳
https://blog.csdn.net/chunniaozheng2370/article/details/101061249
snippet
local function get_timestamp(time_str)
-- format "2022-02-25T21:54:07.7164964+08:00"
local _, _, year, month, day, hour, min, sec = string.find(time_str, "(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+)")
return os.time({year=year, month = month, day = day, hour = hour, min = min, sec = sec})
end
15、table.concat
https://blog.csdn.net/LIQIANGEASTSUN/article/details/46592005
http://lua-users.org/wiki/TableLibraryTutorial
tab = {"a", "c", "d", "b"}
--(4)
-- 四个参数,参数一:表(tab),参数二:分隔符 (" - "),
-- 参数三:起始位置(2),参数四:结束连接位置,作用为连
-- 接tab中所有的value,value 间以 " - " 隔开, 从 tab
-- 的第二个value 开始连接,到 tab 的 第 3 个 value结束连接
print( table.concat(tab, " - ", 2, 3))
--> 输出结果: c - d
简单来说就是将table的字符串拼接起来,指定连接符,以及从第几个到第几个元素的拼接;只有table参数是必传的,其他的都是可选的,默认是连接符为空,从头到尾拼接
将table中的元素拼接成字符串,每个元素都必须支持转换成字符串
Concatenate the elements of a table to form a string. Each element must be able to be coerced into a string.
concat will fail on a table that contains tables because they cannot be coerced into strings
table中的数组或者kv对不能被concat,目前来看只有数字和字符串是可以concat的,而且只能是可以下标索引的元素才可以,例如 a = {1,2,3,"hello"} a[4]->"hello",如果出现不能下标访问的,例如a = {1,2,3,x=1,y=2},那么concat只会输出123,后面的x、y都不会拼接输出

并且,下标是跳过非下标访问元素的数值,例如下面的table,下标从1开始,最大的是5,对应的888

16、select函数
https://www.cnblogs.com/wangyueyouyi/p/9915644.html
lua使用...来表示变长参数,{...}表示变长参数的数组,#{...}表示变长参数的长度,
而select函数可以用来返回变长参数的长度,以及指定从第几个参数开始遍历
function fun(...) --此处的...表示可变参数
for i in pairs({...}) do --此处的{...}表示可变参数构成的数组
xxx
end
end
select(n, ...) --数字n表示起点,select(n, ...)返回从起点n到结束的可变参数,比如:
n=3,... 是 0,1,2,3,4,5
则 select(n, ...) 就表示...中从第3个到最后一个的多个数:2,3,4,5。并且2,3,4,5是4个数,不是列表或其他的数据结构
select('#', ...) --返回可变参数的数量
方法1:
function f(...)
print (#{...}))
end
f(1,2,3)>>3
方法2:
function f(...)
local x = {...}
print (#x))
end
f(1,2,3)>>3
17、lua的函数return
这里是特意备注下,lua中函数如果没有在任何语句块直接return的话,必须结束函数
function correct_example()
return
end
function wrong_example()
return
print(123)
end
如果想直接return,则需使用某个语句块,例如if或者do等
function correct_example()
do
return
end
end
18、lua的table都是引用
t1 = {a=123}
t2 = {table1 = t1}
t3 = {table2 = t1}
print(t1.a) -- => 123
print(t2.table1.a) -- => 123
print(t3.table2.a) -- => 123
t1.a=456
print(t1.a) -- => 456
print(t2.table1.a) -- => 456
print(t3.table2.a) -- => 456
所以用lua写代码的时候,特别要注意这点,避免出现预料之外的数据
在lua中,如果数据类型是引用传参的,例如table、string,即使使用了local的限制,都是引用处理,一处修改,别处也会可见。
19、lua避免循环require的处理
lua的require会先判断某个模块是否已经加载了,是的话就直接返回,否则才加载模块数据,因此来避免循环引用的问题。

20、lua数组append元素
使用table.insert
foo = {}
table.insert(foo,"bar")
table.insert(foo,"baz")
21、lua string.find
https://riptutorial.com/lua/example/20535/string-find--introduction-
