打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Lua中__index的用法详解

 当我们访问一个表的不存在的域,返回结果为nil,这是正确的,但并不一定正确。实际上,这种访问触发Lua解释器去查找__index metamethod:如果不存在,返回结果为nil;如果存在则由__index metamethod返回结果。

这个例子的原型是一种继承。假设我们想创建一些表来描述窗口。每一个表必须描述窗口的一些参数,比如:位置,大小,颜色风格等等。所有的这些参数都有默认的值,当我们想要创建窗口的时候只需要给出非默认值的参数即可创建我们需要的窗口。第一种方法是,实现一个表的构造器,对这个表内的每一个缺少域都填上默认值。第二种方法是,创建一个新的窗口去继承一个原型窗口的缺少域。首先,我们实现一个原型和一个构造函数,他们共享一个metatable:

-- create a namespace

Window = {}

-- create the prototype with default values

Window.prototype = {x=0, y=0, width=100, height=100, }

-- create a metatable

Window.mt = {}

-- declare the constructor function

function Window.new (o)

    setmetatable(o, Window.mt)

    return o

end

现在我们定义__index metamethod:

Window.mt.__index = function (table, key)

    return Window.prototype[key]

end

这样一来,我们创建一个新的窗口,然后访问他缺少的域结果如下:

w = Window.new{x=10, y=20}

print(w.width)       --> 100

Lua发现w不存在域width时,但是有一个metatable带有__index域,Lua使用w(the table)和width(缺少的值)来调用__index metamethod,metamethod则通过访问原型表(prototype)获取缺少的域的结果。

__index metamethod在继承中的使用非常常见,所以Lua提供了一个更简洁的使用方式。__index metamethod不需要非是一个函数,他也可以是一个表。但它是一个函数的时候,Lua将table和缺少的域作为参数调用这个函数;当他是一个表的时候,Lua将在这个表中看是否有缺少的域。所以,上面的那个例子可以使用第二种方式简单的改写为:

Window.mt.__index = Window.prototype

现在,当Lua查找metatable的__index域时,他发现window.prototype的值,它是一个表,所以Lua将访问这个表来获取缺少的值,也就是说它相当于执行:

Window.prototype["藏宝阁-www.gamecbg.com"]

将一个表作为__index metamethod使用,提供了一种廉价而简单的实现单继承的方法。一个函数的代价虽然稍微高点,但提供了更多的灵活性:我们可以实现多继承,隐藏,和其他一些变异的机制。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Step By Step(Lua元表与元方法)(转)
Lua概念备忘
Lua中实现类的原理
Lua笔记
Lua语言基础汇总(8)
Lua学习之function
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服