为什么需要 self.__index=self?

lua在一个表中查找元素的规则如下:

  1. 在表中查找,如果找到,返回该元素,找不到则继续
  2. 判断该表是否有元表,如果没有元表,返回 nil,有元表则继续。
  3. 判断元表有没有index方法,如果index方法为 nil,则返回nil;如果index方法是一个表,则重复1、2、3;如果index 方法是一个函数,则返回该函数的返回值。

我的疑惑: 为什么需要把__index设置为自己?

回答: 因为需要遵守lua第三条规则。

  1. lua
  2. local person = {name = 'default', age = 0}
  3. function person:eat()
  4. print(self.name .. ' 该吃饭了, 饿死了')
  5. end
  6. -- 代码段一
  7. function person:new(o)
  8. o = o or {}
  9. setmetatable(o, self)
  10. self.__index = self
  11. return o
  12. end
  13. local p = person:new()
  14. print(p.name) -- default
  15. -- 代码段二
  16. function person:new1(o)
  17. o = o or {}
  18. setmetatable(o, self)
  19. -- self.__index = self
  20. return o
  21. end
  22. local p1 = person:new1()
  23. print(p1.name) -- nil

上面两个print的结果是不一样的。 p1.name查找逻辑是现在自己的表中找,没找到然后去person这个元表去找,但是因为person中没有实现__index元方法,所以就返回nil。

lua如何实现多态?

  1. lua
  2. local person = {name = 'default', age = 0}
  3. function person:new()
  4. local o = {}
  5. setmetatable(o, self)
  6. self.__index = self
  7. return o
  8. end
  9. function person:eat()
  10. print('person eat')
  11. end
  12. local boy = person:new()
  13. -- 会调用person的方法
  14. boy:eat() -- person eat
  15. -- 重写eat的方法
  16. function boy:eat()
  17. print('boy eat')
  18. end
  19. -- 调用eat的方案
  20. boy:eat()

上面代码就是一个简单的多态例子。