首页 > 其他分享 >Lua学习笔记3

Lua学习笔记3

时间:2024-03-01 17:11:49浏览次数:17  
标签:function end name -- self 笔记 学习 Lua print

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

image-20240226114314735

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

image-20240226115340363

错误处理

调试

垃圾回收

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"))

image-20240226153735954

面向对象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

image-20240226175048950

学有疑问:在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()

image-20240226182706400

简单继承练习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())   

image-20240227103520350

高级语言知识—

函数闭包:

函数闭包是由一个函数和它本身所有的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

image-20240227114454818

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())

image-20240227134522028

元表

遍历访问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

image-20240227143124742

此处通过调用元表中的__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

image-20240227145655581

综上可以理解,元表本身是一个普通的表,通过特定的方法(例如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("-------------------------------")

image-20240227153402837


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

且遍历时候大

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

image-20240301170214218

标签:function,end,name,--,self,笔记,学习,Lua,print
From: https://www.cnblogs.com/TonyCode/p/18047521

相关文章

  • Graph Contrastive Learning with Adaptive Augmentation 论文阅读笔记
    Abstract​ 尽管图CL方法得到了繁荣的发展,但图增强方案的设计——CL中的一个关键组成部分——仍然很少被探索。我们认为,数据增强方案应该保留图的内在结构和属性,这将迫使模型学习对不重要的节点和边缘的扰动不敏感的表示。然而,现有的方法大多采用统一的数据增强方案,如统一丢弃边......
  • 读书笔记
    软件质量属性的一级指标及其在《高性能网站建设指南》中的应用摘要:本文针对软件质量属性的一级指标展开研究,以《高性能网站建设指南》为参考文献,探讨了在网站建设过程中软件质量属性的重要性及其一级指标的具体应用。通过对软件质量属性的六个一级指标进行分析,提出了在网站建设......
  • 系统科学方法概论第五章读书笔记
    第五章主要介绍了自组织系统方法、自组织曰系统理论的历史发展、耗散结构理论简介、协同学简介、突变论简介、自组织系统方法概论、自组织系统理论的历史发展:自组织系统理论研究的是系统在没有外部指令的情况下,通过内部的相互作用和自适应过程,自发的形成有序结构或模式的现象。它......
  • 程序是怎样跑起来的第12章读书笔记
    第12章让计算机思考,程序就如同是计算机执行的各种指令罗列起来的文章。计算机内部的cpu,通过对该文章的内容进行解析和运行,来运至连接到计算机的各种外围设备就好作为工具的程序和为了思考的程序,程序的使用目的大致分为两类,一类是大家作为工具来使用,另一个目的则是程序来代替人类执......
  • 程序是怎样跑起来的第11章读书笔记
    第11章围绕硬件控制方法来展开,第一小节通过一个问题应用和硬件无关来阐述系统调用等原理,Windows提供了通过应用来间接控制硬件的方法。用操作系统提供的系统调用功能就可以实现对硬件的控制。在Windows系统中系统调用称为API,通过使用抽象的接口和标准的编程模型,应用程序可以与底......
  • Vue学习笔记31--自定义指令--函数式
    Vue学习笔记-自定义指令<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>自定义指令</title&......
  • 程序是怎样跑起来的第九章读书笔记
    第九章则告诉我们操作系统和应用的关系第九章分为五个小节来阐述首先介绍了操作系统的历史操作穷的发展是一个逐渐演讲的过程。早教操作系统主要关注于简单的任务调度和硬件管理。随着计算机技术的不断进步,操作系统的功能也变得越来越复杂、包括内存管理、进程管理、文件系统管理......
  • 程序是怎样跑起来的第七章读书笔记
    第七章围绕程序是在和的环境中运行的来展开介绍7.1告诉我们运行环境等于操作系统加组件,操作系统和硬件是运行环境的重要组成部分不同的操作系统和硬件组合可能会导致,软件在不同的环境中表现出不同的行为。Windows操作系统在一定程度上解决了CPU以外的硬件差异问题使得软件在不同......
  • 程序是怎样跑起来的第六章读书笔记
    第六章的主题是文件的压缩通过询问读者为什么文件可以压缩来展开文件压缩机制的讲解6.1我们可以了解到,文件是以字节为单位的保存,每个字节可以表示一个字符、一个数字或其他类型的数据。在文件系统中,文件的大小通常以字节为单位来衡量。通过对字节的读取和写入计算机可以实现对文件......
  • 读书笔记3
    第三章软件工程师的成长这章主要讨论软件工程师个人能力衡量及发展,一些思维误区和以后的职业发展在团队工作中,稳定、一致的交付时间时衡量一个员工能力的重要方面初级软件工程师的成长包括以下几种:(1)积累软件开发相关的知识,提升技术技能(如对具体技术的掌握,动手能力)。例如:对JAV......