“环境” setfenv getfenv
我们任何变量的值都是在堆上保存着,我们的变量名只是这个变量值的引用,这些引用或许是有一个引用的作用域链在维护管理它们的使用范围,
一,元表
table 和 userdata可以有各自独立的元表。其他类型默认情况下没有元表。
可以通过元表来修改一个值的行为,使其在面对一个非预定义的操作时执行一个指定的操作。
setmetatable( t , t1 ) 设置t的元表 为t1
assert( getmetatable( t ) == t1 )
print( getmetatable( “hi”) ) -->table:xxxxxxx
print( getmetatable(10) ) -->nil
local mt = {}
........in Set.new..........
.........
setmetatable( set , mt )
...........
二,元方法:(存在于元表里面的特殊方法,一般以__开头)
将元方法加入元表 mt.__add = Set.union
这样就可以直接调用:
s3 = s1 + s2
每一种算数操作符都有对应的字段名:
__add ==> ‘ + ’ __mul ==> ‘ * ’ __sub ==> ‘ - ’ __div ==> ‘ / ’
__unm 相反数 __mod ==> ’ % ’ __pow(乘幂) __concat(连接操作)
关系类对应元方法:
__eq(等于) __lt(小于) __le(小于等于)
函数getmetatable 和 setmetatable也会用到元表中的一个字段,用于保护元表。__metatable。使用户不能看到,不能修改元表,更何况元表里面的元方法。
mt.__metatable = “not your business”
s1 = Set.new{ }
getmetatable( s1 ) --> ‘not your business’
setmetatable( s1 , { } ) --> stdin:1 cannot change protected metatable
三,table自己访问的元方法
Lua提供一种可以改变table行为的方法。有2种可以改变的table行为:查询table中不存在的字段 , 修改table中不存在的字段
__index :当访问一个table中不存在的字段时,lua会检查是否有__index的元方法。没有它,返回nil,有它,返回这个方法提供的结果。
__index 有2种实现体:function , table
Window.prototype = { x = 0 , y = 0 , width = 200 , height = 200 }
Window.mt = { }
--第一种:(通过这种方式,可以实现多继承,缓存等功能)
Window.mt.__index = function( table , key )
return Window.prototype[key]
end
--第二种:(便捷继承查表方式)
Window.mt._index = Window.prototype
__newindex: 用于table的更新。
当对一个table中不存在的索引赋值的时候,解释器就会查找__newindex元方法。与__index一样,__newindex是个function的话,调用之;__newindex是个table,就在这个table中添加k,v,而不是原来的table
rawset( t , k , v ) 和 rawget( t , i )
四,组合使用__index和__newindex:
具有默认值的table:通过使用__index元方法。
只读的table:
function readOnly( t )
local proxy = { }
local mt = {
__index = t,
__newindex = function( t , k , v )
error(“attempt to update a read-only table” , 2 )
end
}
setmetatable( proxy , mt )
return proxy
end
--创建一个table,然后调用readOnly函数就会使这个table只读。
注意,__index和__newindex应用在查询,修改table中不存在的字段。那么,构造一个proxy是空表,自然什么都是不存在的字段,所以,来自调用者的任何查询和修改都是基于不存在的字段,自然都会找到__index和__newindex的方法,继而,调用之,在这2个方法里面任何操作,随意了。
我们任何变量的值都是在堆上保存着,我们的变量名只是这个变量值的引用,这些引用或许是有一个引用的作用域链在维护管理它们的使用范围,
一,元表
table 和 userdata可以有各自独立的元表。其他类型默认情况下没有元表。
可以通过元表来修改一个值的行为,使其在面对一个非预定义的操作时执行一个指定的操作。
setmetatable( t , t1 ) 设置t的元表 为t1
assert( getmetatable( t ) == t1 )
print( getmetatable( “hi”) ) -->table:xxxxxxx
print( getmetatable(10) ) -->nil
local mt = {}
........in Set.new..........
.........
setmetatable( set , mt )
...........
二,元方法:(存在于元表里面的特殊方法,一般以__开头)
将元方法加入元表 mt.__add = Set.union
这样就可以直接调用:
s3 = s1 + s2
每一种算数操作符都有对应的字段名:
__add ==> ‘ + ’ __mul ==> ‘ * ’ __sub ==> ‘ - ’ __div ==> ‘ / ’
__unm 相反数 __mod ==> ’ % ’ __pow(乘幂) __concat(连接操作)
关系类对应元方法:
__eq(等于) __lt(小于) __le(小于等于)
函数getmetatable 和 setmetatable也会用到元表中的一个字段,用于保护元表。__metatable。使用户不能看到,不能修改元表,更何况元表里面的元方法。
mt.__metatable = “not your business”
s1 = Set.new{ }
getmetatable( s1 ) --> ‘not your business’
setmetatable( s1 , { } ) --> stdin:1 cannot change protected metatable
三,table自己访问的元方法
Lua提供一种可以改变table行为的方法。有2种可以改变的table行为:查询table中不存在的字段 , 修改table中不存在的字段
__index :当访问一个table中不存在的字段时,lua会检查是否有__index的元方法。没有它,返回nil,有它,返回这个方法提供的结果。
__index 有2种实现体:function , table
Window.prototype = { x = 0 , y = 0 , width = 200 , height = 200 }
Window.mt = { }
--第一种:(通过这种方式,可以实现多继承,缓存等功能)
Window.mt.__index = function( table , key )
return Window.prototype[key]
end
--第二种:(便捷继承查表方式)
Window.mt._index = Window.prototype
__newindex: 用于table的更新。
当对一个table中不存在的索引赋值的时候,解释器就会查找__newindex元方法。与__index一样,__newindex是个function的话,调用之;__newindex是个table,就在这个table中添加k,v,而不是原来的table
rawset( t , k , v ) 和 rawget( t , i )
四,组合使用__index和__newindex:
具有默认值的table:通过使用__index元方法。
只读的table:
function readOnly( t )
local proxy = { }
local mt = {
__index = t,
__newindex = function( t , k , v )
error(“attempt to update a read-only table” , 2 )
end
}
setmetatable( proxy , mt )
return proxy
end
--创建一个table,然后调用readOnly函数就会使这个table只读。
注意,__index和__newindex应用在查询,修改table中不存在的字段。那么,构造一个proxy是空表,自然什么都是不存在的字段,所以,来自调用者的任何查询和修改都是基于不存在的字段,自然都会找到__index和__newindex的方法,继而,调用之,在这2个方法里面任何操作,随意了。