问题小记之 使用 nil 索引 Lua table

电玩女神 2021-10-23 12:36 428阅读 0赞

本文简单介绍了使用 nil 索引 Lua table 的一些问题

使用 Lua 已经不少时间了,遇到 “table index is nil” 的错误也很多次了,久而久之自己便形成了 Lua table 索引不能为 nil 的概念.

但实际上,上述概念是不准确的,虽然下面的 Lua 代码确实会引起 “table index is nil” 的错误:

  1. local t = {}
  2. -- use nil as table index
  3. t[nil] = 0

但是如果我们仅使用 nil 为索引进行 table 取值的话,实际上并不会引起错误,仅是返回 nil 罢了:

  1. local t = {}
  2. -- use nil as table index
  3. -- v is nil
  4. local v = t[nil]

网上简单搜索了一下,未找到直接相关的答案,那就直接看看 Lua 源码(5.3.5 版本)吧~

其实答案还是挺简单的:

luaH_get 函数(索引 table 取值会调用到这个函数)中对于索引为 nil 的取值直接返回了 nil (并没有报错):

  1. // ltable.c
  2. const TValue *luaH_get (Table *t, const TValue *key) {
  3. switch (ttype(key)) {
  4. case LUA_TSHRSTR: return luaH_getshortstr(t, tsvalue(key));
  5. case LUA_TNUMINT: return luaH_getint(t, ivalue(key));
  6. // return nil when key is nil
  7. case LUA_TNIL: return luaO_nilobject;
  8. case LUA_TNUMFLT: {
  9. lua_Integer k;
  10. if (luaV_tointeger(key, &k, 0)) /* index is int? */
  11. return luaH_getint(t, k); /* use specialized version */
  12. /* else... */
  13. } /* FALLTHROUGH */
  14. default:
  15. return getgeneric(t, key);
  16. }
  17. }

而在 luaH_newkey 函数中(索引 table 赋值会调用到这个函数),如果索引为 nil 则直接报错了:

  1. // ltable.c
  2. TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
  3. Node *mp;
  4. TValue aux;
  5. // error when key is nil
  6. if (ttisnil(key)) luaG_runerror(L, "table index is nil");
  7. // ...
  8. }

不过从开发角度来讲,个人还是建议统一规避 index 为 nil 的情况,上面提及的 “Lua table 索引不能为 nil” 的概念虽然不准确,但作为开发准则的话却值得坚持~

发表评论

表情:
评论列表 (有 0 条评论,428人围观)

还没有评论,来说两句吧...

相关阅读

    相关 lua-table

    table 是 Lua 的一种数据结构用来帮助我们创建不同的数据类型,如:数字、字典等。 Lua table 使用关联型数组,你可以用任意类型的值来作数组的索引,但这个值不能

    相关 Lua 基础弱引用 table

    弱引用 table lua 的垃圾回收器只会回收没有引用的对象,有些时候并不能回收程序员认为的垃圾。比如数组里的元素在其它地方已经没有引用了,但因为还在数组中,因此