__index: 定义当table中不存在的key值被试图获取时的行为

通常,我们访问一个表的不存在的域,返回结果为nil。比如:

点击(此处)折叠或打开

  1. tb={a=1,b=2}
  2. print(tb.c)

  3. >> nil
通常,我们觉得表中没有的key,读取肯定是nil,但这儿直觉是正确的么?
计算机的世界没有直觉,只有机制。
实际上,lua 访问一个对象的key时,首先浏览table本身是否包括该key,如果有则返回该key对应的value;如果没有,那么会尝试调用该table的元祖方法__index,如果元祖方法存在那么将会对象本身和查找的key为参数,调用元祖方法,返回值作为该次key获取的返回;如果元祖方法__index也未定义,那么返回nil。

点击(此处)折叠或打开

  1. > tb={a=1,b=2}
  2. > print(tb.c)
  3. nil
  4. > =getmetatable(tb)
  5. nil
上面例子中,由于tb没有设置metatable,所以没有__index元祖方法,所以获取没有定义的tb.c时返回为nil。

下面我们为tb设置一个__index元祖方法,默认返回0。结果如下:

点击(此处)折叠或打开

  1. > tb={a=1,b=2}
  2. > setmetatable(tb, {__index = function(obj, key) return 0 end})
  3. > =tb.c
  4. 0
  5. > =tb.d
  6. 0

实际上,__index也可以是一个table。如果是一个table,那么lua解释器在获取key的时候,会从__index table中查找key并以此为返回:

点击(此处)折叠或打开

  1. > setmetatable(tb, {__index = {dd="keyd", ee="keye"}})
  2. > =print(tb.d)
  3. nil
  4. > =print(tb.dd)
  5. keyd
  6. > =print(tb.ee)
  7. keye
  8. > =print(tb.ff)
  9. nil


在实际使用中,__index 最常见的使用方法是用于对象继承,和定义默认值。

10-27 15:40