Lua里面有一个就目前来说,暂时没用过,但是觉得很有用,可能将来需要用到的东西:元表。
什么是元表,以及元表是做什么的?
就我理解,元表是一种附加属性,是需要依附在一个正儿八经表的上面的,这个表里面可以存放我们需要重定义的一些对表的操作。
比如:在C++或者Java中经常需要将一个坐标封装成一个二维向量的结构体,然后在里面重载一些加减的操作, 因为普通的加减是对于两个数字的,但是当你想让两个二维向量相加的时候,需要将X相加,然后Y相加,然后返回一个二维向量,此时普通的加号就没有办法完成我们的操作了、这个时候我们就要将加号重载一下。然后当调用加号的对象变成二维向量的时候,系统就会使用我们自己重载的加号,完成两个二维向量的加法,然后返回一个二维向量。
元表就是在Lua中做这件事的。比如现在我们访问一个表,但是我们不小心访问到了空值,那么就会返回一个nil,当我们访问表中的空值的时候,不想接收一个nil,想接收一个默认值,此时就需要就会用到元表了。
那么我们应该怎么去给一个普通表设置一个元表或者我们应该怎么获取一个普通表的元表呢?
Lua给我们提供了这么两个接口setmatetable以及getmetatable
使用方法如下:
myTable = {} -- 定义一个初始的表
myMetaTable = {} -- 再定义一个表,一会将这个表,设置为myTable的元表
print(myTable)
print(myMetaTable)
-- 这是两个接口
-- setmetatable的两个参数含义是:将第2个表设置为第1个表的元表,返回拥有元表的第一个表
-- getmetatable:获取到参数表的元表,并返回
myTable =setmetatable(myTable,myMetaTable)
metaTable_From_get = getmetatable(myTable)
-- 打印出来的这个表的地址应该和myMetaTable的地址是一样的
print(metaTable_From_get)
Tip:setmetatable的第一个参数,我们当然可以直接使用{}去构造一个表,看自己喜好了。
上面我们说了一下元表的设置和获取,下面我们说一下元表的注意事项:
注意事项第一节:__metatable
之前我们举例的时候,元表设置的是一个空表,但是实际使用的时候,元表是不能设置成为空表的。元表里面会存放我们自己设置的函数,自己储存的变量,但是变量的key值,要谨慎设置为:__metatable。
可以使用,但是大多数当我们在元表里面设置这个Key值的时候,其实是不希望外部可以更改我们元表里面的元素。
当我们使用__metatable作为元表里面的某一个Key值,此时我们通过getmetatable获取的就是__metatable对应的value,不会获取元表。
-- 将元表里面添加__metatable Key值
myTable = setmetatable({"Lua","C++","Java","C#"},{__metatable = "lock"})
metaTable_From_get = getmetatable(myTable)
print(metaTable_From_get)
控制台输出: