Lua学习笔记3

IO读写

Lua中读写使用自带的I/O库处理文件。

分为简单模式和完全模式。

  • 简单模式(simple model)拥有一个当前输入文件和一个当前输出文件,并且提供针对这些文件相关的操作。

  • 完全模式(complete model) 使用外部的文件句柄来实现。它以一种面对对象的形式,将所有的文件操作定义为文件句柄的方法

    注意:要打开的文件地址。

    打开文件的操作语句:

    file=io.open(filename[,mode])

    其中mode所有的值为:

    模式 描述
    “r” 以只读的方式打开文件,打开的文件要必须存在
    “w” 只写的权限打开文件,若文件存在则文件长度清为0,文件内容会消失。若文件不存在则建立该文件
    “a” 以附加的方式打开只写文件。若文件不存在,则会建立该文件,若文件内容不为空,则写入的数据会加在文件末尾,原文内容会得到保留。
    “r+” 以可读的方式打开文件,该文件必须存在
    “w+” 打开可读写文件,若文件存在则文件长度清零,若文件不存在则建立文件
    “a+” 与a类似,但是文件可读可写
    “b” 二进制模式,如果文件是二进制文件,可以加上b使用
    “+” 加号表示对文件即可读又可写
function IOText()
filename="D:\\UnityProject\\Assets\\Scripts_lua\\Game\\Test\\IO.txt"
--part1 简单模式打开文件练习
--只读方式打开
file = io.open(filename,"r")
io.input(file)
--输出文件的第一行
log(io.read())
--关闭打开的文件
io.close(file) ------------------------------
--以附加的形式打开
file=io.open(filename,"a")
--设置输出的文件
io.output(file)
io.write("----新添加的文字")
io.close(file)
end function IOText1()
filename="D:\\UnityProject\\Assets\\Scripts_lua\\Game\\Test\\IO.txt"
--------------------part2
--完全模式 该模式下可以在同一时间处理多个文件
file=io.open(filename,"r")
log(file:read())
file:close() --以附加的形式打开
file=io.open(filename,"a")
file:write("----第三行新加的文字")
file:close()
end

function IOText2()
--另外可以指定文件内容位置进行读取
filename="D:\\UnityProject\\Assets\\Scripts_lua\\Game\\Test\\IO.txt"
file=io.open(filename,"r")
--定位到倒数18个字符位置
file:seek("end",-18)
log(file:read("*a"))--从当前位置读取到结尾的内容
file:close()
end

错误处理

调试

垃圾回收

Lua语言采取自动内存管理。

这意味着你不用操心新创建的对象需要的内存如何分配出来, 也不用考虑在对象不再被使用后怎样释放它们所占用的内存。

Lua语言中运行着一个垃圾收集器,用来收集所有的死对象(无法访问的内存空间),来完成内存回收管理的工作。Lua中所有用到到内存的结构如字符串、表、协程、函数、内部结构等都会服从自动管理。

Lua实现一个增量标记-扫描收集器。它有两个重要的参数来控制–垃圾收集器间歇率垃圾收集器步进率,使用百分数作为单位!

垃圾收集间歇率:控制垃圾收集器需要在开启新的循环前的等待时间,值越高,开启下一轮的垃圾回收循环需要等待的时间越长,减少垃圾收集器的积极性。此值<100,则直接开启下一轮垃圾回收,无需等待;设置当前值为200时,表示当内存总使用量是之前使用量的2倍时才开启新的循环。

垃圾收集器步进率:收集器的运作速度/内存的分配速度。值越大,表示垃圾收集机制越积极。默认值是200;垃圾回收运作速度是内存分配速度的二倍。(要保证垃圾回收运作速度快于内存分配速度,只有如此内存才能尽可能的被及时补充。)

table2={"apple","pear","orange"}
print("---------------------------------")
print(collectgarbage("count"))
table2=nil
print(collectgarbage("count"))--使用的总内存数
print(collectgarbage("collect"))--进行垃圾回收
print(collectgarbage("count"))

面向对象OOP

Shape={area=0}
--构造函数
function Shape:new (o,side)
o=o or {} --?
setmetatable(o,self)
self.__index=self --?
side=side or 0
self.area=side*side
return o
end
--基础类方法 打印出语句
--使用:表示属于Shape的类中
function Shape:printArea()
print(self.area)
end --新建形状对象
shape1=Shape:new(nil,10)
shape1:printArea()--打印出面积是100

学有疑问:在Lua中‘:’,‘ .’和‘self’的区别用法?

答:https://www.cnblogs.com/suoluo/p/7368276.html

self的不同:https://xushuwei202.github.io/blog/2014/04/12/lua-self/

--面向对象
Account={balance=500}
function Account.withdraw(v)
Account.balance=Account.balance-v
end
--进行设置 ---------------------------------------------------------------
Shape={area=0}
--构造函数
function Shape:new (o,side)
o=o or {} --?
setmetatable(o,self)
self.__index=self --?
side=side or 0
self.area=side*side
return o
end
--基础类方法 打印出语句
--使用:表示属于Shape的类中
function Shape:printArea()
print(self.area)
end --继承
--正方形派生类
Square = Shape:new() --类中的属性
function Square:new (o,side)
o=o or Shape:new(o,side)--父构造器
setmetatable(o,self)
self.__index=self
return o
end
--正方向派生类方法
function Square:printArea()
print("正方形面积为",self.area)
end --矩形派生类
Rectangle = Shape:new()
function Rectangle:new (o,length,breadth)
o=o or Shape:new (o)
setmetatable(o,self)
self.__index=self
self.area=length*breadth
return o
end function Rectangle:printArea()
print("矩形面积:",self.area)
end --新建对象
--新建形状对象
shape1=Shape:new(nil,10)
shape1:printArea() --创建派生类对象--正方形
square1=Square:new(nil,10)
square1:printArea() --创建派生类对象--矩形派生类
rectangle1=Rectangle:new(nil,5,6)
rectangle1:printArea()

简单继承练习2

--简单继承
function CreateRobot(name,id)
local obj={name=name,id=id}
--成员函数
function obj:SetName(name)
self.name=name
end
function obj:GetName()
return self.name
end
function obj:SetId(id)
self.id=id
end
function obj:GetId()
return self.id
end
return obj
end
--派生类继承Robot类
function createFootballRobot(name,id,position)
log("123")
local obj=CreateRobot(name,id)
obj.position="right back"
function obj:SetPosition(p)
self.position=p
end
function obj:GetPosition()
return self.position
end
return obj
end

函数调用:

footballRobot=createFootballRobot("TonyChang",6006,"广州")
print("footballRobot_name:",footballRobot:GetName(),"footballRobot_id",footballRobot:GetId())
print("footballRobot_position",footballRobot:GetPosition())
--更改对象内容
footballRobot:SetId(9009)
footballRobot:SetName("UrusWong")
footballRobot:SetPosition("Beijing")
print("--------------------更改之后----------------------")
print("footballRobot_name:",footballRobot:GetName(),"footballRobot_id",footballRobot:GetId())
print("footballRobot_poisition",footballRobot:GetPosition())

高级语言知识—

函数闭包:

函数闭包是由一个函数和它本身所有的upvalue构成的。

upvalue是指函数中使用的但定义在函数外部的局部变量。

--闭包
--作为结果将倒计时函数返回
function createCountdownTimer(second)
local ms=second*1000 --ms为countDown函数之外的局部变量称之为upvalue 变量的定义初始化在函数外部
--倒计时函数
local function countDown()
ms=ms-1
return ms
end
return countDown--注意返回的是函数名称 不要带括号
end
--函数闭包
--一个函数和它所使用的所有upvalue构成了一个函数闭包

调用

timer1=createCountdownTimer(1)--创建一个倒计时器
--使用倒计时器进行三次倒计时操作
for i=1,3 do
print(timer1())
end

Lua函数闭包和C函数的比较:

Lua函数闭包使函数具有保持其状态的能力,从此意义上来说可以与带静态局部变量的C函数来类比。

但二者有着显著的不同。

在Lua语言中函数作为一种基本数据类型–代表一种对象,可以有自己的状态;

带静态局部变量的C函数来说,它并不是C的一种数据类型,更不会产生什么对象实例,它只是一个静态地址的符号名称。

函数闭包基于对象的实现方式

函数闭包子在对象中实现,将需要隐藏的成员放到一张表中,把该表作为成员函数的upvalue

局限性:基于对象的实现不涉及继承及多态

--函数闭包在对象实例中的解读应用
--eg
function createStudent(name,sid)
local data={name=name, id=sid} --data为obj.SetName,obj.GetName,obj.SetId,obj.GetId的upvalue
local obj={}--需要隐藏的成员放在一张表格里,把表作为成员函数的upvalue
--成员函数
function obj.SetName(name)
data.name=name
end
function obj.GetName()
return data["name"]
--return data.name
end
function obj.SetId(id)
data.id=id
end
function obj.GetId()
return data.id
end
return obj
end --调用
student=createStudent("Jack",1001)
print("studentName:",student.GetName())
print("StudentId:",student.GetId())

元表

遍历访问table,结果为空,之后便会去顺承访问元表,默认访问元表中的__index,因此会打印出 meteable中的元素。

--元表练习
function metatableFun()
local table={}
local metatable={a="Anny",b="and",c="Tom"}
--metatable元表中的__index指向metatable
setmetatable(table, {__index=metatable})
for k,v in pairs(table) do
print(k,"=>",v)
end print("--------------------------")
print(table.a,table.b,table.c)
end

此处通过调用元表中的__add相关的函数,来实现两个table的相加功能。

--用于table相加运算的函数
function add(t1,t2)
assert(#t1==#t2)
local size=#t1
for i=1,size do
t1[i]=t1[i]+t2[i]
end
return t1
end
function metatableFun2()
table1=setmetatable({1,2,3},{__add=add})
table2=setmetatable({9,8,7},{__add=add})
--遍历table1
for k,v in pairs(table1) do
print(k,"=>",v)
end
--遍历table2
for k,v in pairs(table2) do
print(k,"=>",v)
end
print("---------table1+table2--------------")
table1=table1+table2
for i=1,#table1 do
print(table1[i])
end
end

综上可以理解,元表本身是一个普通的表,通过特定的方法(例如setmetatable)设置到某个对象上,进而影响这个对象的行为。一个对象有哪些行为受到元表的影响以及这些行为按照何种方式收到影响是受Lua语言约束的。(例如只能根据元表中的关键字类型来设置相关的函数)元表是Lua最关键的概念之一,内容也很丰富。

--基于原型的继承
Person = {name = "Sam",sex="man"}
--构造函数
function Person:New(extension)
local table=setmetatable(extension or{},self)
self.__index=self --默认访问
return table
end --Person 类的成员方法
function Person :SetName(name)
self.name=name
end
function Person: SetSex(sex)
self.sex=sex
end
function Person:GetName()
return self.name
end
function Person:GetSex()
return self.sex
end --新建对象
--基于原型的继承
person=Person:New()
print("person'name:",person:GetName())
print("person'sex:",person:GetSex())
print("-------------------------------")


补充:table作为类似键值对的数据结构时候,#获取长度为0;

且遍历时候大

![image-20240301165902701](E:\畅知-Lua学习代码文件\Lua学习笔记3.assets\image-20240301165902701.png

Lua学习笔记3的更多相关文章

  1. [转]LUA 学习笔记

    Lua 学习笔记 入门级 一.环境配置 方式一: 1.资源下载http://www.lua.org/download.html 2.用src中的源码创建了一个工程,注释调luac.c中main函数,生 ...

  2. Lua 学习笔记(一)

    Lua学习笔记 1.lua的优势 a.可扩张性     b.简单     c.高效率     d.和平台无关 2.注释 a.单行注释 --        b.多行注释 --[[  --]] 3.类型和 ...

  3. Lua学习笔记6:C++和Lua的相互调用

        曾经一直用C++写代码.话说近期刚换工作.项目组中的是cocos2dx-lua,各种被虐的非常慘啊有木有.     新建cocos2dx-lua项目.打开class能够发现,事实上就是C++项 ...

  4. Lua学习笔记4. coroutine协同程序和文件I/O、错误处理

    Lua学习笔记4. coroutine协同程序和文件I/O.错误处理 coroutine Lua 的协同程序coroutine和线程比较类似,有独立的堆栈.局部变量.独立的指针指令,同时又能共享全局变 ...

  5. (转)Lua学习笔记1:Windows7下使用VS2015搭建Lua开发环境

    Lua学习笔记1:Windows7下使用VS2015搭建Lua开发环境(一)注意:工程必须添加两个宏:“配置属性”/“C或C++”/“预处理器”/“预处理器定义”,添加两个宏:_CRT_SECURE_ ...

  6. Lua学习笔记:面向对象

    Lua学习笔记:面向对象 https://blog.csdn.net/liutianshx2012/article/details/41921077 Lua 中只存在表(Table)这么唯一一种数据结 ...

  7. Lua学习笔记(二):基本语法

    Lua学习指南:http://www.lua.org/manual/ 首先我们要明确的一点是:在Lua中,除了关键字外一切都是变量. Lua关键字 可以查看这个地址:http://www.lua.or ...

  8. Lua学习笔记一

    学习了有一周多了.之前一直不想献丑,但还是记录下这个过程. 第1章  开发软件搭建 1. ubuntu 下lua安装 sudo apt-get install lua5.1 2.win下的环境搭建. ...

  9. lua学习笔记

    工作需要,上周对lua赶进度似地学习了一遍,主要参考<lua中文教程>一书,中间参考一些<lua游戏开发实践>,首先说说这两本书,后者不适合初学,里面是对一个游戏脚本系统进行粗 ...

  10. 【Lua学习笔记之:Lua环境搭建 Windows 不用 visual studio】

    Lua 环境搭建 Windows 不用 visual studio 系统环境:Win7 64bit 联系方式:yexiaopeng1992@126.com 前言: 最近需要学习Unity3d游戏中的热 ...

随机推荐

  1. 【图论】CF1508C Complete the MST

    Problem Link 有一张 \(n\) 个点的完全图,其中 \(m\) 条边已经标有边权.你需要给剩下的边都标上权值,使得所有边权的异或和为 \(0\),并且整张图的最小生成树边权和最小. \( ...

  2. 【发现一个问题】macos m2 下无法使用 x86_64-linux-musl-gcc 链接含有 avx512 指令的 c 代码

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 一开始是使用 golang 中的 cgo 来编译: env ...

  3. 【k哥爬虫普法】爬取数据是否一定构成不正当竞争?

    我国目前并未出台专门针对网络爬虫技术的法律规范,但在司法实践中,相关判决已屡见不鲜,K 哥特设了"K哥爬虫普法"专栏,本栏目通过对真实案例的分析,旨在提高广大爬虫工程师的法律意识, ...

  4. border多层渐变

    .content { margin-top: 19px; border-top: 1px dashed rgba(113, 183, 248, 0.6) !important; border-left ...

  5. 深入浅出Java多线程(一):进程与线程

    引言 大家好,我是你们的老伙计秀才. 在计算机系统的发展历程中,早期的计算机操作模式十分单一和低效.用户只能逐条输入指令,而计算机则按照接收指令的顺序逐一执行,一旦用户停止输入或进行思考,计算机会处于 ...

  6. 思维分析逻辑 6 DAY

    数据仓库研究 大数据体系 日志采集和传输 数据建模 数据管理 数据应用 数据建模 日志传输(原始数据) ODS(原始数据) 用户基础属性表:imei,prov,city,machine 用户文章下发表 ...

  7. NC50381 道路和航线

    题目链接 题目 题目描述 FarmerJohn正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇,编号为1到T.这些城镇之间通过R条道路(编号为1到R)和P条航线(编号为1到P)连 ...

  8. NC14685 加边的无向图

    题目链接 题目 题目描述 给你一个 n 个点,m 条边的无向图,求至少要在这个的基础上加多少条无向边使得任意两个点可达~ 输入描述 第一行两个正整数 n 和 m . 接下来的m行中,每行两个正整数 i ...

  9. ARM 中常用的汇编指令解释汇总

    前言 嵌入式项目中经常涉及到需要通过分析编译后的汇编文件,来确定异常代码,对一些常用的指令进行了汇总. 一.处理器内部数据传输指令 在ARM架构中,包括Cortex-A7处理器内部,有一些专门用于数据 ...

  10. Python subProcess库以及Popen类的使用

    subprocess库是一个十分强大且常用的库,它可以用来调用第三方工具(例如:exe.另一个python文件.命令行工具). 1.常用函数call() :执行由参数提供的命令,把数组作为参数运行命令 ...