别被忽悠了 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 开始计数的?
相关文章:
别被忽悠了 Lua 数组真的也可以从 0 开始索引?
先前我说 Lua 数组从 1 开始不太爽,很多人来纠正我说也可以从 0 开始,比如: local m { [0] 100, 101, 102, 103 }然后访问时 m[0] 也可以正常访问到第 0 个元素,所以 “Lua 给你充分自由度,让你可以从任意下标索引数…...

docker占用磁盘过多问题
我在windows系统上用docker,安装在C盘环境下,我发现C盘占用了大量的空间,查找后发现是docker的映像文件占用的,于是开始清理,中间还踩个坑,记录一下,下次需要的时候方便找。 踩坑 我本想移动映…...
[实时计算flink]使用Python依赖
您可以在Flink Python作业中使用自定义的Python虚拟环境、第三方Python包、JAR包和数据文件等,本文为您介绍如何在Python作业中使用这些依赖。 使用自定义的Python虚拟环境 说明 VVR 4.x仅支持3.7版本的Python虚拟环境,VVR 6.x及以上的版本无此限制&a…...
MySql如何实现分布式锁
本篇我们使用mysql实现一个分布式锁。 环境:mysql8,navicat,maven,springboot2.3.11,mybatis-plus 分布式锁的功能 1,分布式锁使用者位于不同的机器中,锁获取成功之后,才可以对共享资源进行操作 2,锁具有重入的功能:即一个使用…...

「行内揭秘」 SQLynx数据库界的“小众宝藏”?
数据库界的“小众宝藏”?Navicat老大哥地位稳如泰山,但这位“SQLynx”小弟也不容小觑!👀 别看它小众,SQLynx在处理数据库事务上那可是丝毫不含糊,无论你是Windows Linux和Mac,甚至银河麒麟统信都…...

【已解决】【MySQL】IDEA配置数据库 报错 未配置SQL方言 无法使用SQL提示
IDEA配置数据库的步骤 下载插件 添加数据源 新建--->选择数据源MySQL 页面展示: 主机名:一般都是localhost不用改端口:填写自己的端口号用户:填写自己的用户名密码:填写自己设置的密码数据库:填写需要…...

Android 开发 调节声音 SeekBar自定义样式
效果图 xml布局 mipmap/seekbar图片随意一张图都可以,这里我的图就不贴出来了 <SeekBarandroid:id"id/seekBar"android:layout_marginLeft"8dp"android:layout_width"377dp"android:layout_height"8dp"android:layou…...

UART-通用异步收发器
1. UART的基本工作原理 UART通信主要有两个部分构成:发送器和接收器,也就是我们常见的(RX接收,TX发送)两个独立的线路来实现数据的双向传输,由于是异步的,UART并不需要时钟信号,而是…...

Linux——— 信号
文章目录 前言:引入信号生活中的例子信号概念见一见Linux中的信号 浅度理解信号信号处理(浅谈):如何自定义捕捉 信号保存(浅谈) 信号产生系统调用产生异常产生:浅谈除0异常浅谈解引用野指针异常Core &&…...
安全见闻-web安全
web安全 一、web程序简介 1. Web程序的基本构成 2. 工作流程 3. 安全性 二、JavaScript代码库 1. 代码库的概念和用途 2. 常见的代码库 三、框架 1. 常见的前端框架 2. 常见的后端框架 四、数据库 1. 数据库的分类 2. 数据库的潜在漏洞 3. 学习数据库的重要性 五、…...

华为手机卸载系统应用的方法
摘要: 1.手机环境:手机需要开启开发者模式并使用usb连接电脑,并选择文件传输模式 2.电脑环境:使用鸿蒙工具箱进行傻瓜操作或安装adb工具进行命令卸载 3.鸿蒙工具箱和adb工具本质都是使用adb shell pm uninstall -k --user 0 xx…...
力扣算法笔记——生成随机数组
题目信息: 给两个随机数和N,生成M到N的随机不重复数组,且M<N。 示例:输入M 2, N5, 输出 [4,3,2,5]. 思路:洗牌算法,先遍历M到N之间所有的数字,将得到的结果存入一个集合中,将集合从后往前遍历…...

Anaconda和Pycharm超详细安装教程(2024版本+Win11)
详细安装:https://download.csdn.net/download/qq_40379132/89924782 一、安装Anaconda 1.1 下载Anaconda 在官方网站(Free Download | Anaconda)上下载适用于你的操作系统的 Anaconda 安装包。(这里以windows为例)…...
代码随想录:从中后/中前遍历序列构造二叉树
106. 从中序与后序遍历序列构造二叉树 用分治思想,后序遍历是左右中,中序遍历是左中右,后序遍历的最后一个元素就是根节点, 在中序遍历中找到它的位置,它前面的为左子树,后面的为右子树,并能计…...

2-134 基于matlab的图像边缘检测
基于matlab的图像边缘检测,采用六种算子(分别是gabor、拉普拉斯、priwitt、robert、sobel、wallis微分算子),对图象进行边缘检测比较,输出边缘检测结果。可对比效果优劣。程序已调通,可直接运行。 下载源程序请点链接…...

【Java并发编程】线程池详解
一、简介 随着计算机行业的飞速发展,摩尔定律逐渐失效,多核CPU成为主流。使用多线程并行计算逐渐成为开发人员提升服务器性能的基本武器。J.U.C提供的线程池:ThreadPoolExecutor 类,帮助开发人员管理线程并方便地执行并行任务。了…...

ThingsBoard规则链节点:GPS Geofencing Events节点详解
引言 1. GPS Geofencing Events 节点简介 2. 节点配置 3. 使用场景 3.1 物流跟踪 3.2 资产管理 3.3 安全监控 3.4 农业监测 4. 实际项目中的应用 4.1 项目背景 4.2 项目需求 4.3 实现步骤 5. 总结 引言 GPS Geofencing Events 是 ThingsBoard 规则链中的一个重要节…...

Jmeter基础篇(19)JSR223预处理器
前言 JSR223预处理器是Apache JMeter中的一个组件,它允许用户使用任何支持Java Scripting API (JSR 223) 的脚本语言来执行预处理任务。这个功能非常强大,因为它让测试人员能够利用如Groovy、JavaScript(Nashorn引擎)、BeanShell…...
通过js控制css变量
在JavaScript中,你可以通过操作CSS变量(也称为自定义属性)来动态改变样式。CSS变量在CSS中使用 – 前缀定义,例如 --main-color: red;。在JavaScript中,你可以使用 document.documentElement.style.setProperty 方法来…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...