当前位置: 首页 > news >正文

别被忽悠了 Lua 数组真的也可以从 0 开始索引?

先前我说 Lua 数组从 1 开始不太爽,很多人来纠正我说也可以从 0 开始,比如:

local m = { [0] = 100, 101, 102, 103 }

然后访问时 m[0] 也可以正常访问到第 0 个元素,所以 “Lua 给你充分自由度,让你可以从任意下标索引数组”,貌似好像说的很有道理,但是不是这样呢?

我们先用 # 符号打印下上面数组的长度:

print('size', #m)

输出是:3 ,而不是实际元素个数 4,因为 # 就是从 1 开始数起的,所以如果你代码里用了 m[0] ,你也需要额外方式计算长度,同时保证用到这个数组的其他代码也遵从这样计算。

还有一个问题,使用 ipairs 遍历的时候,m[0] 不会被遍历进去:

for i, j in ipairs(m) doprint(i, '->', j)
end

输出是:

1       ->      101
2       ->      102
3       ->      103

看到没,你的 m[0] 没了,即便你写了个 m[0] = 100 ,再 ipairs 那里也不认,Lua 没把他算在整数索引范围。那么如果你创建一个数组从 0 开始索引的话,你就要通知所有用你数组的人,既不能用 # 也不能用 ipairs 来遍历,这种沟通成本和后续无穷的麻烦,你愿意接受吗?

那么你说,我们不用 ipairs ,改用 pairs 来遍历行不行?行,你可以这么写:

for i, j in pairs(m) doprint(i, '->', j)
end

但数组从 0 开始的话,0 元素没有保存在 array part 里,会导致遍历顺序不一样(因为优先遍历 array part),上面代码的输出是:

1       ->      101
2       ->      102
3       ->      103
0       ->      100

看到没,先遍历的 1-3(他们在 array part 里),最后再遍历 hash part 里 0。你喜欢这样的无序遍历的数组么?还是继续坚持 for i = 0, N-1 do 来自己遍历,并通知你的同事这样才能保持顺序。

最后一个问题是,一个 table 中 1-n 的连续整数索引都会被保存到 array part 里,而其他会被保存到 hash part 里,不管是检索还是遍历,都会优先到 array part 里用 O(1) 的方式检索,不行再到 hash part 用非 O(1) 的方式同其他 key 一起检索,那么你 m[0] 是游离在 array part 外的键,不但遍历顺序靠后,没和其他元素放一起,每次检索还有额外代价。

因此 Lua 支持数组从 0 开始索引么?只能说允许你这么用,但是语言层面并不提供足够的支持。

那么又会有人混淆视听的说:“从 1 开始也挺好的啊,我有着并没用什么问题”,但他们是不是忘记了 Lua 是嵌入式语言,要依靠宿主 C 语言提供运行环境,数组从 1 开始的话,和 C 语言宿主存在一个换算的关系,两边都写得话,一会从 0 一会从 1 ,引入了额外的负担,不留神就 BUG 了。

扩展阅读:还有觉得从 1 开始更合理的点这里

为什么 C 语言数组是从 0 开始计数的?

http://www.lryc.cn/news/472839.html

相关文章:

  • docker占用磁盘过多问题
  • [实时计算flink]使用Python依赖
  • MySql如何实现分布式锁
  • 「行内揭秘」 SQLynx数据库界的“小众宝藏”?
  • 【已解决】【MySQL】IDEA配置数据库 报错 未配置SQL方言 无法使用SQL提示
  • js 通过filter 实现扁平化数据tree
  • Android 开发 调节声音 SeekBar自定义样式
  • UART-通用异步收发器
  • Linux——— 信号
  • 安全见闻-web安全
  • 华为手机卸载系统应用的方法
  • 力扣算法笔记——生成随机数组
  • Anaconda和Pycharm超详细安装教程(2024版本+Win11)
  • 代码随想录:从中后/中前遍历序列构造二叉树
  • 2-134 基于matlab的图像边缘检测
  • 【Java并发编程】线程池详解
  • ThingsBoard规则链节点:GPS Geofencing Events节点详解
  • Jmeter基础篇(19)JSR223预处理器
  • 通过js控制css变量
  • Docker:容器化和虚拟化
  • OpenSSL
  • CSS 常见选择器
  • Linux使用Dockerfile部署Tomcat以及jdk
  • LC20. 有效的括号
  • 基于springboot企业微信SCRM管理系统源码带本地搭建教程
  • 【MTMSA】不确定缺失模态下基于情态翻译的多模态情感分析
  • 【php常用公共函数】php获取指定时间段中有那几年并输出年份的起始时间和结束时间
  • CTF-PWN: 什么是_IO_FILE?
  • 前端八股文第二篇
  • springboot汽车保修服务管理系统-计算机毕业设计源码00052