如何简单易懂的理解lua的元表metatable

 我来答
潮飞畅1584
2017-10-11 · TA获得超过1517个赞
知道小有建树答主
回答量:173
采纳率:14%
帮助的人:53.1万
展开全部
Lua 的 metatable 并不只是为了 OO 而存在,但 Lua 的面向对象机理,prototype based object orientation,的确是通过 metatable 而实现的。

简单来说,prototype based OO 的根本特征是不采用「类」这一层抽象,也就是说,所有对象都是没有 class 的 instance。当一个 object 需要某个其他 object 已有的功能时,可以将后者设为自己的 prototype;同一个 object 可以同时作为几个其他 object 共同的 prototype(但反之通常不成立);已指定 prototype 的 object 还可以成为其他 object 的 prototype;一个 object 可以以自己为 prototype。一系列 object 以此方式组成一串 prototype 链,在某个 object 上调用它并未定义的方法或属性时,系统会上溯这条链,依次查看每一级 prototype 是否有定义,直至找到或穷尽到链条终点为止。举例而言,假设有三个维京人,甲会弹弓,乙会用剑,丙会持盾牌;甲给乙当 prototype,于是乙也会了弹弓;乙再给丙当 prototype,丙就成了可以持盾挥剑射弹弓的全能维京人。甲没有 prototype(或者有一个什么都不会的缺省 prototype),丙则不是任何人的 prototype(但他可以是)。
具体到 Lua 这里,这种「向上寻找 prototype」的机制,可以用 metatable 之中的 metamethod 完成。最简单但并不是最简洁的例子:
a = { foo = function() return 'foo' end }

b = { bar = function() return 'bar' end }

c = { __index = b }

setmetatable(a, c)
a.bar()
-- 'bar'

将 table c 的 __index 定义为 table b,然后将 a 的 metatable 定为 c,就让 b 变成了 a 的 prototype。而 c 作为 metatable 的角色其实可以融合到 b 或者 a 中:
a = { foo = function() return 'foo' end }

b = { bar = function() return 'bar' end }

b.__index = b

setmetatable(a, b)
a.bar()
-- 'bar'

这样一来,b 既是 a 的 prototype,也是 a 的 metatable。将 __index 指向另一个 table 大概是它最简单也最普遍的用法,只是 Lua 官方教程中引入 __index 的部分写得比较复杂,把它写成了一个函数,意图大概是考虑到大部分读者对 prototype based OO 并不是很了解(那时候 JavaScript 还没有现在这么流行),所以用 metatable 来强行实现了一个看起来很接近 class-based 的 OO。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
善良的fdgfdr
2017-10-11 · TA获得超过2051个赞
知道小有建树答主
回答量:314
采纳率:34%
帮助的人:102万
展开全部
2、老罗拉了一车梨,
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户
2017-10-11
展开全部
八、让中、英文输入法智能化地出现
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式