Lua查找键
从lua表中查找一个键时的流程:
假设有个lua对象a,查找a中有没有talk方法
a中有没有talk这个键?有--->返回talk
--->没有,是否设置过metatable?没有--->返回nil
--->有,metatable是否有__index这个键?没有--->返回nil
--->有,a中的metatable中的__index这个键对应的表中有没有talk这个键?没有--->返回nil
--->有,返回getmetatable(a)__index.talk
这里有几个点,需要注意:
- Lua查找的是metatable里面的__index不是table里面的。
- 所以直接设置a.__index=super不能实现继承
module,require,package
- require的第一步是去package.loaded这个table里面检查是否已经加载
- 如果已经加载
- 则返回对应的值。
- 如果module没有加载
- require会在package.path中根据Lua文件里面的module名字查找。
- 如果找到
- 则调用loadfile进行加载
- 如果没找到,则在package.cpath中根据名字查找C语言的库文件。
- 如果找到
- 则调用底层函数package.loadlib,返回一个名为luaopen_modname的C语言函数作为Lua的函数
- 如果找到
- 如果找到
- require会在package.path中根据Lua文件里面的module名字查找。
- 如果已经加载
- 无论模块是否找到,require都会得到一个与之对应的加载器。
- require的返回值将会保存在package.loaded这个table中,未来再调用同一个模块,就直接返回。
- 如果希望require同一个模块两次,可以将模块从package.loaded中擦除。package.loaded.modname = nil
布尔值注意事项
Lua中,只有nil和false两个值是False,其它所有值都是True,包括空字符串””、数值0,均为true。
Lua支持not and or三种布尔运算符(没有对应的! && ||),其中not优先级较高,而and和or优先级几乎是所有运算符中最低的
此外,a and b or c绝大多数时候等价于三目运算a ? b : c,但前提是b不能为false。当b为true时:
-
如果a为真,b为真,则a and b返回b,b or c又返回b
-
如果a为假,则a and b返回a,a or c返回c
当b为false时,如果a为true,则a and b返回b,b or c无法保证返回b,所以无法等价于a ? b : c。