Lua菜鸟教程学习笔记四(重难点 续)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/BillCYJ/article/details/83000847

内容会持续更新,有错误的地方欢迎指正,谢谢!

Lua 文件 I/O

Lua I/O 库用于读取和处理文件。分为简单模式(和C一样)、完全模式(以一种面对对象的形式,将所有的文件操作定义为文件句柄的方法)。如果同时读取多个文件的话,使用完全模式则较为合适。

简单模式

以下为 file.lua 文件代码,操作的文件为test.lua(如果没有你需要创建该文件),代码如下:

-- 以只读方式打开文件
file = io.open("test.lua", "r")
-- 设置默认输入文件为 test.lua
io.input(file)
-- 输出文件第一行
print(io.read())
-- 关闭打开的文件
io.close(file)

-- 以附加的方式打开只写文件
file = io.open("test.lua", "a")
-- 设置默认输出文件为 test.lua
io.output(file)
-- 在文件最后一行添加 Lua 注释
io.write("--  test.lua 文件末尾注释")
-- 关闭打开的文件
io.close(file)

完全模式

通常我们需要在同一时间处理多个文件。也就需要使用 file:function_name 来代替 io.function_name 。以下实例演示了如何同时处理同一个文件:

-- 以只读方式打开文件
file = io.open("test.lua", "r")
-- 输出文件第一行
print(file:read())
-- 关闭打开的文件
file:close()

-- 以附加的方式打开只写文件
file = io.open("test.lua", "a")
-- 在文件最后一行添加 Lua 注释
file:write("--  test.lua 文件末尾注释")
-- 关闭打开的文件
file:close()

其中 io.read() 中我们没有带参数,参数可以是下表中的一个
在这里插入图片描述
简单模式和完全模式read 的参数完全相同。

Lua 错误处理

语法错误

-- test.lua 文件
a == 2
-- 以上代码执行结果为:
lua: test.lua:2: syntax error near '==' 
-- 2是第二行的意思,syntax error是语法错误的意思
for a= 1,10
   print(a)
end
-- 执行以上程序会出现如下错误:
lua: test2.lua:2: 'do' expected near 'print'

运行错误

编译是可以成功的,但在运行的时候会产生错误:

function add(a,b)
   return a+b
end
add(10)

运行时,报错如下:

lua: hello.lua:2: attempt to perform arithmetic on local 'b' (a nil value)
stack traceback:(堆栈信息)
	hello.lua:2: in function 'add'
	hello.lua:4: in main chunk
	[C]: ?

错误处理

常用assert 和 error 来处理错误
1.assert检查参数,若参数没问题,assert不做任何事情;否则,assert以参数作为错误信息抛出。
assert举例:assert(type(b) == "number", "b 不是一个数字") 当b不是数字时就输出“lua: test.lua:1: b 不是一个数字”
2.error终止正在执行的函数,并返回message的内容作为错误信息

Lua 调试(Debug)

Lua 提供了 debug 库用于提供创建我们自定义调试器的功能。Lua 本身并未有内置的调试器,但很多开发者共享了他们的 Lua 调试器代码。
Lua 中 debug 库包含了十多个函数,举例如下:

function myfunction ()
print(debug.traceback("Stack trace"))
print(debug.getinfo(1))
print("Stack trace end")
    return 10
end
myfunction ()
print(debug.getinfo(1))
--  执行以上代码输出结果为:

Stack trace
stack traceback:
    test2.lua:2: in function 'myfunction'
    test2.lua:8: in main chunk
    [C]: ?
table: 0054C6C8
Stack trace end

在上面这个实例中,我们用到了 debug 库的 traceback 和 getinfo 函数, getinfo 函数用于返回函数信息的表。

调试类型

1.命令行调试,命令行调试器有:RemDebug、clidebugger、ctrace、xdbLua、LuaInterface - Debugger、Rldb、ModDebug
2.图形界面调试,图形界调试器有:SciTE、Decoda、ZeroBrane Studio、akdebugger、luaedit

Lua 垃圾回收

Lua 采用了自动内存管理,类似于GC。 这意味着你不用操心新创建的对象需要的内存如何分配出来, 也不用考虑在对象不再被使用后怎样释放它们所占用的内存。
Lua 实现了一个增量标记-扫描收集器,它使用这两个数字来控制垃圾收集循环: 垃圾收集器间歇率和垃圾收集器步进倍率。

  1. 垃圾收集器间歇率控制着收集器需要在开启新的循环前要等待多久。 增大这个值会减少收集器的积极性。 当这个值比 100 小的时候,收集器在开启新的循环前不会有等待。 设置这个值为 200 就会让收集器等到总内存使用量达到之前的两倍时才开始新的循环。
  2. 垃圾收集器步进倍率控制着收集器运作速度相对于内存分配速度的倍率。 增大这个值不仅会让收集器更加积极,还会增加每个增量步骤的长度。 不要把这个值设得小于 100 , 那样的话收集器就工作的太慢了以至于永远都干不完一个循环。 默认值是 200 ,这表示收集器以内存分配的"两倍"速工作(每次 Lua 使用的内存翻倍时,就做一次完整的收集)。
    以下演示了一个简单的垃圾回收实例:
mytable = {"apple", "orange", "banana"}
print(collectgarbage("count")) -- 以 K 字节数为单位返回 Lua 使用的总内存数
mytable = nil
print(collectgarbage("count"))
print(collectgarbage("collect")) -- 做一次完整的垃圾收集循
print(collectgarbage("count"))

执行以上程序,输出结果如下(注意内存使用的变化):

20.9560546875
20.9853515625
0
19.4111328125

Lua 面向对象

对象由属性和方法组成。Lua中最基本的结构是table,所以需要用table来描述对象的属性;Lua中的function可以用来表示方法。那么Lua中的类可以通过table + function模拟出来。

以下我们演示了 Lua 面向对象的完整实例,包含创建对象,访问属性、成员函数,继承等多个面向对象的知识点:

 -- Meta class
Shape = {area = 0}
-- 基础类方法 new
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
-- 基础类方法 printArea
function Shape:printArea ()
  print("面积为 ",self.area) -- 可以使用点号(.)来访问类的属性
end
-- 创建对象
myshape = Shape:new(nil,10) -- 创建对象是为类的实例分配内存的过程
myshape:printArea() -- 可以使用冒号 : 来访问类的成员函数
--------------------------------------
Square = Shape:new()
-- 派生类方法 new
function Square:new (o,side)
  o = o or Shape:new(o,side)
  setmetatable(o, self)
  self.__index = self
  return o
end
-- 派生类方法 printArea
function Square:printArea ()
  print("正方形面积为 ",self.area)
end
-- 创建对象
mysquare = Square:new(nil,10)
mysquare:printArea()
--------------------------------------
Rectangle = Shape:new()
-- 派生类方法 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
-- 派生类方法 printArea
function Rectangle:printArea ()
  print("矩形面积为 ",self.area)
end
-- 创建对象
myrectangle = Rectangle:new(nil,10,20)
myrectangle:printArea()

执行以上程序,输出结果为:

面积为     100
正方形面积为     100
矩形面积为     200

总结:至于继承,可以通过metetable模拟出来,但不推荐用,因为只需要模拟出最基本的对象,大部分时间都够用了。

Lua 数据库访问

Lua 数据库的操作库:LuaSQL

猜你喜欢

转载自blog.csdn.net/BillCYJ/article/details/83000847
今日推荐