Lua学习笔记(五)

Lua模块与包

模块类似于一个封装库

创建方法:

  • 创建一个table
  • 把需要导出的常量、函数放入其中
  • 返回该table
-- 文件名为mymodule.lua
-- 定义一个名为mymodule的模块
mymodule={}

-- 定义一个常量
mymodule.constant="这是一个常量"

-- 定义一个函数
function mymodule.func1()
    io.write("这是一个公有函数!\n")
end

local function func2()
    print("这是一个私有函数!")
end

function module.func3()
    func2()
end

return mymodule

require函数

-- require函数用于加载模块,使用方法:
require("mymodule")
require "mymodule"

-- 执行require后返回由模块常量或函数组成的table,并且还会定义一个包含该table的全局变量
require("mymodule")
print(module.constant)
mymodule.func3()

-- 也可以创建别名
local m=require("mymodule")
print(m.constant)
m.func3()

加载机制:

https://www.runoob.com/lua/lua-modules-packages.html

Metatable(元表)

元表允许改变table的行为,每个行为关联了对应的元方法

--[[
作用:对指定的table设置metatable
参数列表:
	table:操作对象
	metatable:元表
返回值:绑定好对象的table
]]
setmetatable(table,metatable)

--[[
作用:返回对象的元表
参数列表:
	table:操作对象
返回值:元表
]]
getmetatable(table)

__index元方法

-- 当使用table中的某个键key时,会查找table中的该键key,如果没有这个键key则会寻找该table的metatable中的_index键,如果__index包含一个table,Lua会在表格中查找键值为key的元素
other={foo=3}
t=setmetatable({},{_index=other})	-- t中没有foo键,调用foo是在metatable中查找__index对应的table,再在该table上查找foo键
t.foo		-- 输出:3

-- __index 元方法查看表中元素是否存在,如果不存在,返回结果为 nil;如果存在则由 __index 返回结果。如果__index包含一个函数,Lua就会调用该函数,table和键作为参数传递给函数。
mytable=setmetatable({key1="value1"},{
        __index=function(mytable,key)
            if key == "key2" then
                return "metatablevalue"
            else
                return nil
            end
        end
    })

print(mytable.key1,mytable.key2)
--[[
输出结果:
value1	metatablevalue
]]

Lua查找table元素规则:

  1. 在表中查找,如果找到,返回该元素,找不到则继续

  2. 判断该表是否有元表,如果没有元表,返回 nil,有元表则继续

  3. 判断元表有没有__index方法,如果__index方法为nil,返回nil;如果__index方法是一个表,则重复1、2、3;如果__index方法是一个函数,则返回该函数的返回值

__newindex元方法

-- __newindex方法用于对表更新,__index则用来对表访问
-- 给表的一个缺少的索引赋值,解释器就会查找__newindex 元方法:如果存在则调用这个函数而不进行赋值操作
mymetatable={}
mytable=setmetatable({key1="value1"},{__newindex=mymetatable})
print(mytable.key1)
mytable.newkey="新值2"
print(mytable.newkey,mymetatable.newkey)
mytable.key1 = "新值1"
print(mytable.key1,mymetatable.key1)
--[[
输出结果:
value1
nil	新值2
新值1	nil
]]

-- 如果__newindex元方法是一个函数,则会把该table,该key,该value作为参数传进函数
mytable = setmetatable({key1 = "value1"}, {
	__newindex = function(mytable, key, value)
		rawset(mytable, key, "\""..value.."\"")
	end
})
mytable.key1 = "new value"
mytable.key2 = 4
print(mytable.key1,mytable.key2)
--[[
输出结果:
new value	"4"
]]

为表添加操作符(类似于运算符重载)

元方法 对应运算符
__add +
__sub -(减号)
__mul *
__div /
__mod %
_unm -(负号)
__concat ..
__eq ==
__lt <
__le <=

__call元方法

-- __call元方法在该表被当成函数来调用时会调用
mytable=setmetatable({10},{
        __call=function(mytable,newtable)
            local sum=0
            for i=1,#mytable do
                sum=sum+mytable[i]
           	end
            for i=1,#newtable do
                sum=sum+newtable[i]
            end
            return sum
        end
    })
newtable={10,20,30}
print(mytable(newtable))	-- 输出结果:70

__tostring元方法

-- __tostring 元方法用于修改表的输出行为
mytable = setmetatable({ 10, 20, 30 }, {
	__tostring = function(mytable)
		local sum = 0
		for k, v in pairs(mytable) do
         	sum = sum + v
         end
    	return "表所有元素的和为 " .. sum
    end
})
print(mytable)	-- 输出结果:表所有元素的和为 60
posted @ 2019-07-20 11:01  Jaxes  阅读(201)  评论(0编辑  收藏  举报