setmetatable (table, metatable)
Sets the metatable for the given table.
You cannot change the metatable of other types from Lua, only from C.
If metatable
is nil, removes the metatable of the given table.
If the original metatable has a "__metatable"
field, raises an error.
This function returns table
.
如果,metatable为空,可以删除table的metatable.
getmetatable (object)
If object does not have a metatable, returns nil.
Otherwise, if the object's metatable has a "__metatable" field, returns the associated value.
Otherwise, returns the metatable of the given object.
如果object中没有metatable,则返回nil.
如果object中的metatable有一个__metatable字段,则返回关联值。
如果object中存在metatable,那就返回metatable
Every value in Lua can have a metatable. This metatable is an ordinary Lua table that defines the behavior of the original value under certain special operations.
在LUA语言中每一个值都有一个metatable.这个metatable是一个定义了特殊操作的table.
Tables and full userdata have individual metatables (although multiple tables and userdata can share their metatables).
table和full userdata有单独的metatables.虽然多个table和userdate可以共享同一个metatable。
A metatable controls how an object behaves in arithmetic operations, order comparisons, concatenation, length operation, and indexing.
metatable控制一个对象的数学操作。
A metatable also can define a function to be called when a userdata is garbage collected.
metatable同时也可以定义一个对象的GC调用的方法。
For each of these operations Lua associates a specific key called an event.
When Lua performs one of these operations over a value, it checks whether this value has a metatable with the corresponding event.
If so, the value associated with that key (the metamethod) controls how Lua will perform the operation.
Each operation is identified by its corresponding name. The key for each operation is a string with its name prefixed by two underscores, '__
';
metatable控制着这些数学操作,GC操作通过特殊的名字。这些操作的名字以“__”作为前缀。
//在LUA调用C API.LUA_BASE_LIB
static int luaB_getmetatable (lua_State *L)
{
//检查参数数量
luaL_checkany(L, 1);
if (!lua_getmetatable(L, 1))
{
lua_pushnil(L);
return 1; /* no metatable */
}
//获取__metatable字段并且返回到LUA语言中
luaL_getmetafield(L, 1, "__metatable");
return 1; /* returns either __metatable field (if present) or metatable */
}
static int luaB_setmetatable (lua_State *L)
{
//检查setmetatable(table,metatable)函数的参数数量。
int t = lua_type(L, 2);
//检查类型是否为Table
luaL_checktype(L, 1, LUA_TTABLE);
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table expected");
//判断table是否存在metatable字段
if (luaL_getmetafield(L, 1, "__metatable"))
luaL_error(L, "cannot change a protected metatable");
lua_settop(L, 2);
lua_setmetatable(L, 1);
return 1;
}