【Lua进阶系列】之Lua元方法案例+字段
大家好,我是Lampard~~
欢迎来到Lua进阶系列的博客
前文再续,书接上一回。今天和大家讲解一下lua中的元方法
__index字段
说起lua那么就不得不提其元表,lua通过元表的设置实现了高级语言中的“继承”的功能。
当我们访问一个表中不存在的元素时,会执行以下三个步骤:
1.lua会判断这个表是否有元表,若无则返回nil
2.若存在着元表,则会判断元表是否存在__index字段,若无则返回nil
(这样子是取不到c的值的)
3.若元表中存在着__index字段,若__index对应的值是一个函数则得到函数的返回值
若对应的是一个表则在该表中寻找想要的值,若有则返回,若无则重复123
__newindex
如果说__index字段是在访问表中不存在的值是执行的操作的话
那么__nexindex字段则是在对表中不存在的值进行赋值时候执行的操作(记住i是小写)
在这个时候可能有人吐槽:纳尼!!我天天给表创建新字段,咋不见得有执行什么__newindex呢?
确实,如果没有元表,或者元表中没有__newindex字段则就是普通新建一个字段而已
若存在元表且元表中存在着__newindex字段,且__nexindex字段是一个函数,则会执行这个函数
若__nexindex字段是表会怎么样呢?
我们可以看到,当我们输出myTable.c时,lua是找不到这个值的,也就是说虽然yourTable中存在着c的值,但是它不能像__index字段那样,把这个值当做myTable的值输出。好玩的来了,我们不是对myTable.c赋值过了吗?那为什么还是nil呢?从结果我们可以看到,其实这个3我们是赋值给了yourTable.c, 总结来说,就是当__nexindex字段是表的时候,它会吃掉外表的新字段赋值,但是却不能从外表中访问得到。
那么这个__newindex字段有何作用呢?其实它可以起到一个很好的限制筛选作用。可以防止表被赋值,加入些杂七杂八的元素。有时候一表多用可能会导致些lua中的垃圾回收相关的问题。
__call
__call元方法比较好玩,比如说我们上述例子中的myTable是外部引用的一个表。那如果我把它当成一个函数使用会怎么样呢?
print(myTable(1, 2))
毫无疑问是会报错的哈,但是__call方法能够帮助我们实现解决这个问题
比如说我们的myTable和yourTable都是一个序列(num类型的),我想求出这两个序列的总和
这个时候可能有同学会问:搞那么复杂干嘛咧,我们直接先遍历一遍myTable,再遍历一遍yourTable不就好了吗?或者说我直接在myTable中添加一个新的函数字段,实现同样的功能不也一样吗?
诚然功能确实是一样的,但是如果我们需要频繁的利用这个外表(myTable)去生成或取得某一些内容时,利用__call方法会简便许多你说是myTable(XX)方便还是myTable.函数名(XX)方便?
__tostring
__tostring 元方法用于修改表的输出行为 ,如果我们直接print()一个表,那么我们返回得到的是一个地址。
而如果我们通过设置其元表的__tostring字段,那么返回的就是你想要的结果。
比如上面的例子就是输出自己的序列和,记住__tostring返回的是一个字符串,不然会报错。
眼尖的同学可能立刻就发现了,阿西,你这里的sum不就是一个num吗?
但是lua在print一个num的时候会自动把它转化为string类型, 但是不是所有的类型都会自动转换的
__le,__eq, __lt,__add, __pow,__mod
这三个元方法分别对应:小于等于,等于,小于,加法,乘幂,取模等
当我们对两个表进行大小比较,或者加减乘除乘幂取模的时候。
lua会查看元表中是否有对应的字段,若有则执行相关的函数,没有则会报错。