lua __call 测试,模拟 OOP 设计

local normal_tbl = {}
normal_tbl("test1", "test2", "test3")

把 normal_tbl 表对象当作函数来使用,会怎么样?

如下图,会报错:
在这里插入图片描述
给 normal_tbl 添加一个元表,并给该元表对象加上 __call

local mtbl = {}
normal_tbl.__name = "normal_tbl"
mtbl.__name = "mtbl"

setmetatable(normal_tbl, mtbl)
mtbl.__call = function(self, ...)
	print("self.name : " .. tostring(self.__name), ...)
end

这时候,我们再调用 normal_tbl(…)

normal_tbl("test1", "test2", "test3") -- self.name : normal_tbl	test1	test2	test3

输出了对应的数值

这有什么用呢,我们可以把他当作 类蓝图对象的构造函数 来使用


实例类似 OOP

下面模拟 OOP 中有使用到 __index,可以参考:lua __index 测试

还有:

  • getmetatable
  • __name

等,都可以参考官方文档,不过 __name 说是 tostring() 再错误时有使用到的

但是我试过,不行!-_-!

所以我还时明文调用: tostring(tbl.__name) 来输出

-- 模拟 oop 语言 定义一个类,可以指定他的名字字段、和他的基类
function class(name, base_cls)

	print("define class, name : " .. name)

	if base_cls then
		print(name .. " have base_cls : " .. tostring(base_cls.__name))
	else
		print(name .. " have no base_cls")
	end

	local cls = {}
	local mtbl = {}
	cls.__name = name
	cls.__index = cls
	mtbl.__name = name
	mtbl.__index = base_cls -- 设置基类
	mtbl.__call = function(self, ...) --[=[self 是 cls]=] return cls.new(self, ...) end
	setmetatable(cls, mtbl)

	-- 调用带继承层级的构造函数
	function _call_ctor_inherit(cls, self, ...)
		-- 递归继承的metatable
		local _base_cls = getmetatable(cls)
		if _base_cls then
			print("check inherit ctor, in : " .. _base_cls.__name)
			if _base_cls and _base_cls.__index and type(_base_cls.__index) == "table" then
				_call_ctor_inherit(_base_cls.__index, self)
			end
		end

		-- 如果有构造函数就调用
		-- 这里不要使用 obj.ctor,因为可能会查找到 __index 里面去了,所以使用 rawget 来获取原始对象信息,这就可以绕过 __index 的索引查找
		-- local ctor = obj.ctor
		local ctor = rawget(cls, "ctor")
		if ctor then
			print(cls.__name .. " have ctor")
			ctor(self, ...)
		else
			print(cls.__name .. " have no ctor")
		end
	end

	function cls.new(self, ...)
		-- self 是 cls
		print(self.__name .. " __call function, with args : ", ...)
		local new_obj = { __name = self.__name }

		-- 给示例化对象设置类接口元表
		setmetatable(new_obj, self)

		-- 调用带继承层级的构造函数
		_call_ctor_inherit(self, new_obj, ...)

		print("return new_obj.namne :" .. new_obj.__name .. ", new_obj : " .. tostring(new_obj))
		-- 返回创建的对象
		return new_obj
	end
	-- 注意返回的是一个类
	return  cls
end

local HumanCls = class("HumanCls")
-- 给 HumanCls 添加 ctor 构造函数
HumanCls.ctor = function(self, ...)
	print(self.__name .. ".ctor")
end
_G[HumanCls.__name] = HumanCls -- 给 "HumanCls" 注册到 _G

local TomCls = class("TomCls", HumanCls)
-- 给 TomCls 添加 ctor 构造函数
TomCls.ctor = function(self, ...)
	print(self.__name .. ".ctor")
end
_G[TomCls.__name] = TomCls -- 给 "TomCls" 注册到 _G

function test_new_tom()
	local tom = TomCls("arg1", "arg2")
	print("tom.name : " .. tostring(tom.__name) .. ", tom : " .. tostring(tom))
end

test_new_tom()

输出:

--[=[
define class, name : HumanCls
HumanCls have no base_cls
define class, name : TomCls
TomCls have base_cls : HumanCls
TomCls __call function, with args : 	arg1	arg2
check inherit ctor, in : TomCls
check inherit ctor, in : HumanCls
HumanCls have ctor
HumanCls.ctor
TomCls have ctor
TomCls.ctor
return new_obj.namne :TomCls, new_obj : table: 009D2DD0
tom.name : TomCls, tom : table: 009D2DD0
]=]

然后我们将继承层级弄深一些,并且将构造函数值设置一部分,再看看结果:

-- 下面我们可以把继承层级弄深一些,并且将 .ctor 构造函数值设置一部分,再看看输出信息

local BASE_CLS = class("Base_CLS")
local CLS_A = class("CLS_A", BASE_CLS)
local CLS_B = class("CLS_B", CLS_A)
local CLS_C = class("CLS_C", CLS_B)
local CLS_D = class("CLS_D", CLS_C)

-- CLS_A、CLS_D 都不设置构造函数

CLS_B.ctor = function(self)
	print("CLS_B.ctor run, inst.name : " .. self.__name)
end
CLS_C.ctor = function(self)
	print("CLS_C.ctor run, inst.name : " .. self.__name)
end

local new_d = CLS_D("arg1", "arg2", "arg3")
print("new_d.cls__name : " .. new_d.__name)

再看看输出:

--[=[
define class, name : Base_CLS
Base_CLS have no base_cls
define class, name : CLS_A
CLS_A have base_cls : Base_CLS
define class, name : CLS_B
CLS_B have base_cls : CLS_A
define class, name : CLS_C
CLS_C have base_cls : CLS_B
define class, name : CLS_D
CLS_D have base_cls : CLS_C
CLS_D __call function, with args : 	arg1	arg2	arg3
check inherit ctor, in : CLS_D
check inherit ctor, in : CLS_C
check inherit ctor, in : CLS_B
check inherit ctor, in : CLS_A
check inherit ctor, in : Base_CLS
Base_CLS have no ctor
CLS_A have no ctor
CLS_B have ctor
CLS_B.ctor run, inst.name : CLS_D
CLS_C have ctor
CLS_C.ctor run, inst.name : CLS_D
CLS_D have no ctor
return new_obj.namne :CLS_D, new_obj : table: 009DDB88
new_d.cls__name : CLS_D
]=]

References

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值