【Lua基础 第5章 】unpack()和pack()、Lua 中的文件 I/O、简单模式下io的部分方法、完全模式下file的部分方法、日期和时间、闭包使用

简介: unpack()和pack()、Lua 中的文件 I/O、简单模式下io的部分方法、完全模式下file的部分方法、日期和时间、闭包使用

💨更多相关知识👇

💖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,你的支持是对作者最大的鼓励,不足之处可以在评论区多多指正,交流学习

目录
相关文章
|
13天前
|
Java
缓冲流和转换流的使用【 File类+IO流知识回顾③】
这篇文章介绍了Java中缓冲流(BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter)和转换流(InputStreamReader, OutputStreamWriter)的使用,包括它们的构造方法和如何利用它们提高IO操作的效率及处理字符编码问题。
缓冲流和转换流的使用【 File类+IO流知识回顾③】
|
13天前
|
存储 Java 调度
FileInputStream,FileOutputStream 和 FileReader ,FileWriter 类的基本使用【 File类+IO流知识回顾②】
这篇文章回顾了Java中FileInputStream、FileOutputStream、FileReader和FileWriter类的基本使用方法,包括读取和写入文件的操作,以及字符流和字节流的区别和应用场景。
FileInputStream,FileOutputStream 和 FileReader ,FileWriter 类的基本使用【 File类+IO流知识回顾②】
|
13天前
|
Java
File类的基本使用【 File类+IO流知识回顾①】
这篇文章回顾了Java中File类的基本使用,包括创建File对象、获取文件数据信息、判断文件存在与否、创建和删除文件目录,以及遍历文件目录的方法。
File类的基本使用【 File类+IO流知识回顾①】
|
13天前
|
存储 Java
序列化流 ObjectInputStream 和 ObjectOutputStream 的基本使用【 File类+IO流知识回顾④】
这篇文章介绍了Java中ObjectInputStream和ObjectOutputStream类的基本使用,这两个类用于实现对象的序列化和反序列化。文章解释了序列化的概念、如何通过实现Serializable接口来实现序列化,以及如何使用transient关键字标记不需要序列化的属性。接着,通过示例代码演示了如何使用ObjectOutputStream进行对象的序列化和ObjectInputStream进行反序列化。
序列化流 ObjectInputStream 和 ObjectOutputStream 的基本使用【 File类+IO流知识回顾④】
|
20天前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
|
2月前
|
Java
IO流操作-------File类、输入流和输出流(二)
这篇文章介绍了Java中IO流操作的基本概念和使用,包括字节流和字符流的读取与写入,以及如何使用缓冲流提高文件读写效率和实现文件复制的方法。
IO流操作-------File类、输入流和输出流(二)
|
1月前
|
Linux C语言
C语言 文件IO (系统调用)
本文介绍了Linux系统调用中的文件I/O操作,包括文件描述符、`open`、`read`、`write`、`lseek`、`close`、`dup`、`dup2`等函数,以及如何获取文件属性信息(`stat`)、用户信息(`getpwuid`)和组信息(`getgrgid`)。此外还介绍了目录操作函数如`opendir`、`readdir`、`rewinddir`和`closedir`,并提供了相关示例代码。系统调用直接与内核交互,没有缓冲机制,效率相对较低,但实时性更高。
|
2月前
|
存储 监控 Linux
性能分析之从 IO 高定位到具体文件
【8月更文挑战第21天】性能分析之从 IO 高定位到具体文件
30 0
性能分析之从 IO 高定位到具体文件
|
2月前
IO流拷贝文件的几种方式
IO流拷贝文件的几种方式
31 1
|
2月前
|
Java
IO流操作-------File类(一)
这篇文章介绍了Java中File类的常用操作,包括创建文件/文件夹、删除文件、查询文件属性(如存在性、大小、名称、路径)以及递归遍历文件夹下所有文件的方法。
IO流操作-------File类(一)