通常,我们访问一个表的不存在的域,返回结果为nil。比如:
点击(此处)折叠或打开
- tb={a=1,b=2}
- print(tb.c)
- >> nil
计算机的世界没有直觉,只有机制。
实际上,lua 访问一个对象的key时,首先浏览table本身是否包括该key,如果有则返回该key对应的value;如果没有,那么会尝试调用该table的元祖方法__index,如果元祖方法存在那么将会对象本身和查找的key为参数,调用元祖方法,返回值作为该次key获取的返回;如果元祖方法__index也未定义,那么返回nil。
点击(此处)折叠或打开
- > tb={a=1,b=2}
- > print(tb.c)
- nil
- > =getmetatable(tb)
- nil
下面我们为tb设置一个__index元祖方法,默认返回0。结果如下:
点击(此处)折叠或打开
- > tb={a=1,b=2}
- > setmetatable(tb, {__index = function(obj, key) return 0 end})
- > =tb.c
- 0
- > =tb.d
- 0
实际上,__index也可以是一个table。如果是一个table,那么lua解释器在获取key的时候,会从__index table中查找key并以此为返回:
点击(此处)折叠或打开
- > setmetatable(tb, {__index = {dd="keyd", ee="keye"}})
- > =print(tb.d)
- nil
- > =print(tb.dd)
- keyd
- > =print(tb.ee)
- keye
- > =print(tb.ff)
- nil
在实际使用中,__index 最常见的使用方法是用于对象继承,和定义默认值。