最近在读取CSV文件并通过Lua表遍历时,发现每次重新运行Lua程序后,遍历Lua表的键值顺序都有不同。Lua表的内部是数组+哈希表实现的,读取CSV文件的键值顺序是固定的,插入Lua表以及遍历Lua表键值的顺序也应该是固定的。
经过测试,只有以字符串为键时才会出现上述情况。我查阅了readinglua以及lua的源码,摘录如下:
在Lua表的插入luaH_newkey的实现中,会调用mainposition获取需要插入的目标地址,而对于短字符串LUA_TSHRSTR是调用hashstr来实现的:
#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
#define hashstr(t,str) hashpow2(t, (str)->hash)
而短字符串的hash值构造如下:
随机数种子的计算如下:
每次重新运行Lua虚拟机后,都会重新构造随机数种子以计算短字符串的hash值,导致同一字符串的hash值在两次Lua虚拟机运行中改变,在Lua表中插入的顺序自然也就受到了影响。