RustRover 中最常见的 Rust 编译器错误(下)| 技术解析
在上期博客中,我们根据 RustRover 的使用数据深入分析了 10 大最常见 Rust 编译器错误中的后 5 个。在本部分中,我们将探讨最常发生的前 5 大错误,并对 Rust 编程语言中最容易使开发者与编译器产生“冲突”的方面进行一些更总体的观察。
常见错误 #5:E0433(使用了未声明的 crate、模块或类型)
这个错误类似于上一部分中谈到的 E0432(import 未解析)。唯一的区别是,具有问题组件的路径直接在名称中使用,不带 use
子句。17.5% 的 RustRover 用户遇到过这个错误。例如,在下面的代码中,编译器无法理解我们真正的意图(crate 还是模块)并报错:
这个示例展示了 Rust 编译器备受好评的错误消息传递。即使不阅读消息,修正也显而易见:验证名称,根据需要将所需的依赖项添加到Cargo.toml,或者引入适当的 import。
RustRover 也可以发挥作用, 让我们选择导入的名称。
编写代码时使用代码补全就可以完全避免这种错误。
常见错误 #4:E0425(使用了未解析的名称)
接下来是另一个“未解析”的错误。20.5% 的 RustRover 用户遇到过这种情况:使用了未解析的名称,它在语法上不是 crate 或模块名称。发生这种错误时会弹出:
当然,实际发生时,情况可能不会像上图中那样明朗。
可惜,即使是了不起的 Rust 编译器也难以应对这种错误。可以采取的方式是:修订名称、提供定义或引入适当的 import。
常见错误 #3:E0599(方法用于未实现该方法的类型)
剧透预警:从现在起都将是类型检查错误!没错,前三名的错误都与不正确的类型使用相关。这里的错误是,27.5% 的 RustRover 用户曾试图在未实现方法的类型的值调用上该方法。来看下面的例子:
fn main() {
let numbers: Vec = vec![4, 11, 15, 12];
let sum: usize = numbers.sum();
println!("Answer = {sum}");
}
看起来没问题,只是没有作用于 Vec
的 sum
方法。具体错误消息如下:
error[E0599]: `Vec` is not an iterator
这里的修正是首先调用 iter
方法,然后在生成的迭代器上使用 sum
。
另外,RustRover 有一项功能可以防止这种错误, 即链式补全。要查看实际益处,请查看以下示例:
当补全建议被采纳时,iter
和 sum
方法都会添加到调用链中,立即修正代码。
通常,代码补全可以帮助您避免 E0599 消息。如果您没有看到所需方法调用的建议,那么真正的问题可能是被调用方类型不正确。
这个错误还有一个方面值得一提:在许多上下文中,您可以控制自己的类型声明。一种选项是首先调用一个方法,然后按 Alt-Enter (⌥Option–Return) 并执行建议的操作让 RustRover 搭建其实现:
操作的结果是,RustRover 生成方法实现模板,同时考虑到有关类型的所有上下文信息:
impl Info {
pub(crate) fn summary(&self) -> String {
todo!()
}
}
运行这段代码会导致运行时错误,但至少编译器不再报错。
常见错误 #2:E0308(预期类型与接收的类型不匹配)
设想一下:在需要类型 B
的值的上下文中使用了类型 A
的表达式。这里的“上下文”可以指调用点处的函数形参、变量声明、控制流语句/表达式等。如果您遇到过这个问题,那么您也是 30% 的 RustRover 用户中的一员。
理论上,对于这种情况我们有两种选择:调整值或调整上下文。调整值可能涉及转换类型、引用/解引用、在值上调用转换方法或将其替换为其他内容。调整上下文并不总是可行,有时我们可以更改预期类型来匹配接收的类型。
RustRover 通过提供快速修复选项支持两种操作模式,例如:
注意列表中的第二个建议:在这种情况下,RustRover 提出了适合编译器的相当复杂的值转换。遵循第一个建议将修正上下文,即函数定义。
常见错误 #1:E0277(尝试使用一个类型,但该类型未在需要特征的位置实现特征)
我们终于到榜首了!RustRover 中最常见的 Rust 编译器错误是 E0277, 32% 的 RustRover 用户经历过这种以类型和特征为主题的开发者噩梦。像往常一样,官方说明很好地提供了示例并解释了可能的修正。我们来关注 RustRover 的行为。
对于这种错误,我最喜欢的 RustRover 功能如下所示:
编译器报错:
error[E0277]: `Info` doesn't implement `std::fmt::Display`
当然,实现 Display
特征是其中一种选择,RustRover 也很乐意搭建实现。但在这种情况下,我更倾向于采用第一个建议,其中涉及两个同时进行的步骤:
-
派生
Debug
特征的实现。 -
更改格式字符串以调用
Debug
特征的格式化功能。
然而,在许多其他情况下,RustRover 无法自行发现和高亮显示此错误。如前一部分所述,它的类型检查功能还没有那么强大,但我们正在改进。作为最常见的错误消息,E0277 当然在我们的关注范围之内。
Rust 错误的总体观察
我们来看概况。上周,我们向 X(以前称为 Twitter)社区询问 Rust 编程语言的什么方面是代码错误的主要来源。以下是我们得到的回复:
为了将社区回复与我们从数据中观察到的结果进行比较,我们研究了 25 个最常见的 Rust 编译器错误,并将其大致分为五类:
-
类型和特征
-
所有权和生命周期
-
宏
-
未解析的名称或不存在的元素
-
其他
结果如下(按错误代码数字从小到大的顺序排列):
错误代码 | 描述 | 类别 |
E0061 | 调用函数时传递的实参数量无效 | 其他 |
E0063 | 未提供结构或类结构枚举变体的字段。 | 未解析/不存在 |
E0106 | 此错误表明类型缺少生命周期。 | 所有权和生命周期 |
E0107 | 提供的泛型实参数量不正确。 | 类型和特征 |
E0277 | 尝试使用一个类型,但该类型未在需要特征的位置实现特征 | 类型和特征 |
E0282 | 编译器无法推断类型并要求类型注解。 | 类型和特征 |
E0283 | 由于缺乏信息无法明确选择实现。 | 类型和特征 |
E0308 | 预期类型与接收的类型不匹配。 | 类型和特征 |
E0369 | 尝试对不支持的类型进行二元运算。 | 类型和特征 |
E0382 | 内容移动到其他位置后变量才被使用。 | 所有权和生命周期 |
E0412 | 使用的类型名称不在作用域内。 | 未解析/不存在 |
E0423 | 标识符像函数名称一样使用,或者需要一个值并且标识符存在,但它属于不同的命名空间。 | 未解析/不存在 |
E0425 | 使用了未解析的名称。 | 未解析/不存在 |
E0432 | import 未解析。 | 未解析/不存在 |
E0433 | 使用了未声明的 crate、模块或类型。 | 未解析/不存在 |
E0502 | 已被借用为不可变对象的变量被借用为可变对象。 | 所有权和生命周期 |
E0507 | 借用的值被移出。 | 所有权和生命周期 |
E0515 | 返回了对局部变量的引用。 | 所有权和生命周期 |
E0596 | 发生此错误是因为您尝试以可变方式借用不可变变量。 | 所有权和生命周期 |
E0597 | 发生此错误是因为值在借用期间被删除。 | 所有权和生命周期 |
E0599 | 发生此错误是因为方法用于未实现该方法的类型。 | 类型和特征 |
E0609 | 尝试访问结构中不存在的字段。 | 未解析/不存在 |
E0614 | 尝试解引用无法解引用的变量。 | 其他 |
E0658 | 使用了不稳定的函数。 | 其他 |
E0716 | 临时值正被删除,而借用仍在有效使用中。 | 所有权和生命周期 |
很遗憾,我们掌握的数据并没有太多关于宏的信息。我们既无法可靠地检测宏展开问题,也无法识别源自成功展开的宏的其他错误。也许这表明我们应该对收集的数据进行更精细的分类。
不考虑宏,前 25 大常见错误中似乎没有明显的赢家,这说明我们平等地喜爱 Rust 的每一面:
-
类型和特征 – 7 个错误
-
所有权和生命周期 – 8 个错误
-
未解析的名称或不存在的元素 – 7 个错误
-
其他 – 3 个错误
概要
在本系列的这一部分中,我们研究了 RustRover 中的五大最常见 Rust 编译器错误。其中三种错误与类型和特征有关,表明这一错误类别对于正确编写 Rust 代码颇为关键。我们观察了 25 个最常见错误的总体数据,意识到 Rust 的其他方面也会导致我们经常遇到的错误。
本博文英文原作者:Vitaly Bragilevsky
RustRover 相关阅读
⏬ 戳「阅读原文」了解更多信息
本文分享自微信公众号 - JetBrains(JetBrainsChina)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
云原生 API 网关链路追踪能力重磅上线
云原生API网关介绍 云原生API网关是腾讯云基于开源网关推出的一款高性能高可用的云原生API网关产品,作为云上流量入口,集成请求分发、API管理、流量监控、访问限制等功能,是微服务架构和容器架构中的重要组件。 TSE云原生API网关提供多可用区容灾部署、多种接入方式统一管理能力、开箱即用的限流熔断、流量灰度、流量镜像、安全防护等能力。对于存在流量波峰波谷性质的业务,TSE云原生API网关同样支持弹性伸缩和定时伸缩实现对网关节点的伸缩。 云原生API网关优势 ●超强性能:通过云原生API网关可以轻松应对百万并发 ●无限的可扩展性:依托开源生态,具有丰富的社区插件,同时支持自定义插件 ●集中且简单的管理:在一个控制台上就能管理服务、路由、安全等配置 ●丰富的流量管理和监控:提供开箱即用的限流、熔断、灰度、流量镜像等流量管理和监控能力 ●原生支持容器和微服务生态:100%Kubernetes原生架构和接口让您充分利用Kubernetes强大能力,支持对接多种注册中心,轻松访问管理您的微服务 ●全链路高可用:网关入口、网关节点,全链路支持多可用区部署,保证高可用 客户在链路追踪场景中遇到的疑...
- 下一篇
京东物流基于 StarRocks 的数据分析平台建设
作者:京东物流 数据专家 刘敬斌 小编导读: 京东集团 2007 年开始自建物流,2017 年 4 月正式成立京东物流集团,截至目前,京东物流已经构建了一套全面的智能物流系统,实现服务自动化、运营数字化及决策智能化。 京东物流在运营数字化及决策智能化过程中,实时化运营分析的业务需求越来越多,原有平台架构中的数据孤岛、查询性能低、运维难度大、开发效率低等问题日益凸显。2022 年,京东物流基于 StarRocks 打造了 Udata 统一查询引擎,高效解决了数据服务与数据分析的众多痛点。 近两年来,京东物流在 StarRocks 的使用中不断进行性能提升优化,取得了良好的效果。在 StarRocks Summit 2023 上,京东物流数据专家刘敬斌为大家介绍了 StarRocks 的应用经验,并重点分享了湖仓查询的优化经验和效果。另外,据刘敬斌介绍,在 2023 年京东双十一大促期间,京东物流 StarRocks 集群规模已经达到了 3 万核以上。 京东物流的用数特征和痛点 一个企业的业务特征决定了用户的用数习惯,而用数习惯往往会演变出一些用数痛点,在京东物流的数据分析服务场景中存在 ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7设置SWAP分区,小内存服务器的救世主
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS8编译安装MySQL8.0.19
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题