💨更多相关知识👇
💖Spring中的创建对象的三种方式、第三方资源配置管理详细描述及使用(XML版完结篇)
💖Spring中的bean的配置、作用范围、生命周期详细描述及使用(XML版上篇)
💖Spring中的依赖注入、setter与构造器注入、自动装配与集合注入详细描述及使用(XML版中篇)
🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈
🍂个人博客首页: KJ.JK
💖系列专栏:JavaEE进阶教程系列
一、table.unpack()和table.pack()
"table.unpack(): 该函数的参数是一个数组,返回值为数组内的所有元素"
如: print(table.unpack{10,20,30}) -- 这里是{}不是() -- 10 20 30
"table.pack(): 可以将所有参数打包成一个table并返回"
二、Lua 中的文件 I/O
Lua I/O 库用于读取和处理文件; 分为简单模式(和C一样)、完全模式
* 简单模式(simple model): 拥有一个当前输入文件和一个当前输出文件,并且提供针对这些文件相关的操作 (每次只能操作单个文件)
* 完全模式(complete model): 使用外部的文件句柄来实现。它以一种面对对象的形式,将所有的文件操作定义为文件句柄的方法 (可以在同一时间处理多个文件)
"简单模式在做一些简单的文件操作时较为合适。但是在进行一些高级的文件操作的时候,简单模式就显得力不从心。例如同时读取多个文件这样的操作,使用完全模式则较为合适"
🔸打开文件
file = io.open (filename [, mode])
/*
--filename: 文件名
--mode : 打开的格式
*/
模式 | 描述 | |
---|---|---|
r | 以只读方式打开文件,该文件必须存在 | |
w | 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件 | |
a | 以追加的方式打开只写文件;若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留(EOF符保留) | |
r+ | 以可读写方式打开文件,该文件必须存在 | |
w+ | 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件 | |
a+ | 与a类似,但此文件可读可写 | |
b | 二进制模式,如果文件是二进制文件,可以加上b | |
+ | 号表示对文件既可以读也可以写 |
🌟简单模式下的文件读取与写入代码演示
"文件读取"
-- 打开文件
file=io.open("demo","r")
-- 读取文件
io.input(file)
-- 打印文件内容
print(io.read())
io.close()
---------------------------------------------------------------------------------
"文件写入"
-- 写文件
file2=io.open("demo","w")
-- 输出文件
io.output(file2)
-- 写出内容
io.write("我是刚刚写的文件")
io.close()
🔸io.read的参数(file:read的参数也一样是这个)
模式 | 描述 | |
---|---|---|
" *n " | 读取一个数字并返回它; 例:file.read("*n") | |
" *a " | 从当前位置读取整个文件; 例:file.read("*a") | |
" *l "(默认) | 读取下一行,在文件尾 (EOF) 处返回 nil; 例:file.read("*l") | |
number | 返回一个指定字符个数的字符串,或在 EOF 时返回 nil;例:file.read(5) |
🌟完全模式代码演示
-- 以只读方式打开文件
file = io.open("demo", "r")
-- 输出文件第一行
print(file:read())
-- 关闭打开的文件
file:close()
-- 以附加的方式打开只写文件
file = io.open("demo", "a")
-- 在文件最后一行添加 Lua 注释
file:write("--test")
-- 关闭打开的文件
file:close()
三、简单模式下io的部分方法
"io.tmpfile():返回一个临时文件句柄,该文件以更新模式打开,程序结束时自动删除"
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
"io.type(file): 检测obj是否一个可用的文件句柄"
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
"io.flush(): 向文件写入缓冲中的所有数据"
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
"io.lines(optional file name): 返回一个迭代函数,每次调用将获得文件中的一行内容,当到文件尾时,将返回 nil,但不关闭文件"
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
"io.lines(optional file name): 打开指定的文件 filename 为读模式并返回一个迭代函数,每次调用将获得文件中的一行内容,当到文件尾时,将返回 nil,并自 动关闭文件。若不带参数时io.lines() <=> io.input():lines(); 读取默认输入设备的内容,但结束时不关闭文件"
四、完全模式下file的部分方法
"file:seek(optional whence, optional offset): 设置和获取当前文件位置,成功则返回最终的文件位置(按字节),失败则返回nil加错误信息"
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
参数 whence 值可以是:
"set": 从文件头开始
"cur": 从当前位置开始[默认]
"end": 从文件尾开始
"offset":默认为0
"file:seek()":不带参数则返回当前位置
"file:seek("set")":则定位到文件头
"file:seek("end")":则定位到文件尾并返回文件大小
"file:flush()": 向文件写入缓冲中的所有数据
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- 以只读方式打开文件
file = io.open("demo", "r")
file:seek("set",1) -- 从文件倒数第1个位置开始,不包括第一个
print(file:read("*a"))
-- 关闭打开的文件
file:close()
五、日期和时间
"os.time(): 直接返回一个当前时间的时间戳 从1970年1月1日的秒数"
如: print(os.time()) --- 1635088147
-- os.time还支持反向转换,把对应的year,month,day传过去,hour,min,sec字段如果不提供
-- 默认为12:00:00,其他字段(wday和yday)会被忽略
--------------------------------------------------------------------------------------------------------------------------------
"os.date:这个其实是os.time的反函数,比如说,我们把时间戳输入,那么就可以转化为一个表(用格式化字符串*t,就可以把时间戳转化为日期格式的表)"
如:
t = os.date("*t", 1635088102)
for k, v in pairs(t) do
print(k, v)
end
--------------------------------------------------------------------------------------------------------------------------------
"os.date的指示符"
min 36
day 28
hour 19
year 2022
month 9
isdst false
sec 47
yday 271
wday 4
--------------------------------------------------------------------------------------------------------------------------------
"os.difftime: 计算两个日期的差"
local t1 = os.time({year=2021,month=1,day=2})
local t2 = os.time({year=2011,month=2,day=3})
local d = os.difftime(t1,t2)
print(d) --- 312854400.0
六、os.date的指示符
七、闭包
🔹词法定界
"当一个函数内嵌套另一个函数的时候,内函数可以访问外部函数的局部变量,这种特征叫做词法定界"
table.sort(names,functin (n1,n2)
return grades[n1]>grades[n2]
end)
--内部匿名函数可以访问外部函数的n1,n2
🔹第一类值
"能把函数像普通数值一样赋值给变量,可以作为参数传递给其他函数,可以作为函数的返回值"
如:
a = { p = print } --’ a.p 指向 print 函数
a.p ( "Hello Wold") --> Hello Wo ld
print =math. sin -- 'print 现在指向 sine 函数
a.p(print(1)) --> 0.8414709848079
🔹作用域(Scope)
"作用域是指变量、函数等起作用的范围,可以分为三种,分别是:" "全局作用域、函数作用域 和 块作用域"
"全局作用域:在全局都可以访问"
"函数作用域:只有在函数内部可以访问"
"块作用域:在当前语句块中起作用,比如 if 语句块或者 else 语句块"
🔹生命周期
"生命周期是指: 变量可以被访问的时间段,也就是从分配内存给它到回收它的内存中间的一段时间"
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
"变量的生命周期分为两种"
"1.在栈中分配内存的变量,它的生命周期随着作用域的结束而结束"
"2.在堆中分配内存的变量,它的生命周期与作用域不一致,比如在堆中申请的内存,退出作用域后仍然存在"
Lua采用了自动内存管理,不用操心Lua创建的对象是怎么分配和回收
在Lua语言中声明的变量默认是全局变量,声明局部变量需要使用local关键字,只要不是local标明都是全局变量
a = 10
function func()
b = 10 -- 仍然是全局变量
local c = 20 -- 局部变量
end
func()
print(a + b) --> 20,即可以获取b的值
print(c) --> nil
🔹闭包
闭包是指"能够读取其他函数内部变量的函数,它缓存上级的作用域,使得函数外部打破了
"函数作用域"的束缚,可以访问函数内部的变量"(读取其他函数内部变量的函数)
在Lua中,闭包(closure)是由"一个函数和该函数会访问到的非局部变量(或者是upvalue)组成
的",其中非局部变量(non-local variable)是指不是在局部作用范围内定义的一个变量,但同时又不
是一个全局变量,主要应用在嵌套函数和匿名函数"里,因此若一个闭包没有会访问的非局部变量,那么它就是通常说的函数
--------------------------------------------------------------------------------------------------------------------------------
"实现闭包的需要解决的两个问题"
"1.函数是第一类值(first class value),也就是要能把函数像普通数值一样赋值给变量,可以作为参数传递给其他函数,可以作为函数的返回值(函数是严格遵循词法作用域的第一类值,具备了实现闭包的条件)"
"2.满足词法作用域(Lexical Scope),要让内层函数能够访问外层函数中的变量,不管外层函数退出与否"
--------------------------------------------------------------------------------------------------------------------------------
简单来说就是: "对于一个函数,能够访问到外部函数的非全局变量的一种机制"
如:
function func1 ()
local x = 1
function func2 () -- 定义一个内部函数
print(x)
end
func2() -- 执行这个内部函数
end
func1()
"外部调用了func1函数,而func1中定义了一个func2函数并调用了它。我们可以看到,func2访问了属于func1的local变量x,并且访问成功了;"
"按道理来讲,x并不是全局函数,也不是func2的局部函数,应该是访问不到的。而lua却做到了,lua把实现这个功能的方式定义为闭包"
作者:KJ.JK
文章对你有所帮助的话,欢迎给个赞或者 star,你的支持是对作者最大的鼓励,不足之处可以在评论区多多指正,交流学习