• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

在Rust中编程:好,坏,丑。

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
这篇文章是关于我通过解决Twitch上尚未解决的所有CtCI问题来学习Rust的经验。
英国科学博物馆集团Ada Lovelace的肖像
Rust徽标,由Mozilla提供,CC-BY

Rust是一种现代系统级编程 语言 ,在设计时考虑了安全性。 它提供了零成本的抽象,泛型,功能特性以及更多其他功能。 最近,我开始努力正确地学习Rust,并希望分享一些想法。

直到最近,我只在Rust中编写了一些小程序,在阅读了“ Programming Rust”的一半内容之后,我真的不了解 Rust。 我认为了解该语言的一种好方法是解决“**编码面试”一书中的所有189个问题 我不仅会用Rust来解决问题,而且决定在Twitch上进行开发 在技​​术讲座或在观众面前编码的过程中,我并不陌生,但是尝试学习一种编程语言,并解释自己的所作所为-对我来说是鲜活的事情-对我来说是新鲜事物。

事情开始有点粗糙:技术问题,流问题,工具问题,而且我一开始就很难理解内存范例。 试图做到这一点,同时还向人们解释我在做什么,这很棘手

我花了大约8个小时来实现一个链接列表:我记录了两个4个小时的流,试图弄清楚如何正确使用Rc,RefCell和Box。 有一段时间,我觉得我只是在敲击键盘尝试随机组合,直到卡住了。 令人惊奇的是,人们收看了。 我一定做对了。

在脱机阅读了一些之后(并阅读了非常有帮助的“ 使用太多的链表来学习Rust ”),这些概念开始为我所吸引。 完成链接列表的实现后,事情变得简单了。

Rust中的链接列表。 VSCode与RLS紧密集成

我现在已经进入了本书的第4章,我觉得自己已经迈出了大步。 编译后,Rust感觉自然,高效且令人非常满意。 Rust具有强类型性,并提供出色的编译器消息:如果您设法安抚了编译器,那么您的代码很有可能会工作-除非存在任何逻辑缺陷。

Rust的一个可爱功能是编译器可以提供多大帮助。 例如,众所周知,C ++代码的编译器消息很难解密。 尽管Clang的错误消息已取得了长足的进步,但Rust的编译器的帮助又高了一个数量级。

rustc的错误输出示例

到目前为止,我将总结一些发现。 这是基于我最初的反应,我承认我缺乏Rust的专业知识,但是对于其他人来说,看看他们的经验与我的经验相比可能仍然很有趣。 我很遗憾地承认我没有对下面的每个问题进行彻底的研究,因此我可能已经过时或信息不正确。

语言:善良

首先,对Rust团队以及为该项目做出贡献的每个人都表示敬意。 这是我有过的最有趣的编程语言学习经历之一。 我不知道Rust是否会像其他语言一样吸引开发人员的注意力,但是我认为它会持续存在。 关于细节:

  • Rust代码非常易于阅读,并且不会因为难以解析C ++或Scala等语言的语法而受苦。 它似乎具有我期望的功能,而挑战仅在于确定要调用的函数。
  • 具有诸如map()filter()find()类的功能特性很令人高兴。 定义高阶函数并将闭包传递给它们很容易。 它并没有使函数式编程像Ruby这样的语言那么容易,但是很接近。 实际上,令人惊讶的是,与C / C ++相比,一种语言的功能是如此容易。
  • Rust迫使您认真考虑内存分配,因为您别无选择。 最后,这意味着草率的代码难以编写,而好的代码则易于编写。 这些抽象也直接映射为编写安全的并发代码。
  • Rust的零成本抽象使编写好的代码变得容易,而又不增加开销。 特性可以提供现代的编程抽象,而不会降低性能。
  • Rust代码是安全的(前提是您不使用unsafe关键字,或调出不安全的C库)
  • Rust的ResultOption提供了一种处理可能返回值的函数或可能包含值的变量的好方法。 在C,C ++甚至Java中,常见的模式是函数在没有任何返回值时返回空指针。 在大多数情况下,当这种情况意外发生时,会导致某人的时间不好。

语言:不好

  • 我发现as_ref()需要as_ref() unwrap()as_ref()borrow()有点冗长。 我希望可以使用一些语法糖来减少必须以不同方式将这些调用链接在一起的次数。 我发现自己经常编写类似于option.as_ref().unwrap().borrow()代码,感觉很讨厌。
  • 为了能够在合理的时间内编译代码,需要对编译器进行一定的权衡。 结果,在某些情况下, rustc无法推断类型,或者它需要一些人工帮助才能编译代码。 对我来说,我发现有时很难弄清编译器的需求,以及为什么它对我来说不可行。
  • 有些事情有时会觉得太冗长。 例如,在strString之间进行转换,或者将引用而不是值传递给函数,似乎编译器会为我解决。 我敢肯定有一个很好的理由说明为什么它是如此,但是有时感觉rustc 太正确了
  • 必须处理每个函数的每个Result都是好的; 这意味着程序员必须考虑每个函数调用的情况。 有时会感到乏味。 ? 操作员可以减少一些冗长的细节,但是没有很好的概括方法来处理故障类型。 诸如故障错误链之类的条板箱使此操作变得容易,但是您仍然需要为可能发生的每种错误类型显式定义一个案例。

语言:丑陋

  • 巨集:WTF? 与其他语言相比,Rust宏感觉像是向左拐。 公平地讲,我还无法理解它们,但是它们感觉就像是一些奇怪的螺栓附件,这种附件只是在Perl的启发下设计出来的。 我最终将花一些时间来将来正确地理解它们,但是现在我想避免它们。 像瘟疫。

工具:好

  • Rust提供了不错的工具,并通过RLS与VSCode等IDE集成。 RLS提供了棉绒,代码完成,语法检查和即时格式化的支持。
  • Cargo是Rust强大的包裹管理器:如果您尝试使用Rust,您可能会熟悉它。 在大多数情况下,与Cargo合作是一种乐趣。 已经有大量用于Cargo的插件,可提供其他功能,例如代码覆盖率
  • Cargo还是一个构建系统,可用于运行单元和集成测试。 通过某种程度的声明性TOML语法,可以轻松配置构建和依赖项。
  • Cargo与crates.io集成, crates.io是开源Rust项目的权威资源。 与PyPi或RubyGems一样,您会在crates.io上找到几乎所有其他Rust软件包。
  • rustup是用于管理Rust安装的首选工具。 您可以选择稳定,测试版或夜间频道,并安装所有以前版本的特定内部版本。 它还可以让您安装clippy和rustfmt等组件
  • 如果您是像我这样的完美主义者,那么clippy是必备的代码设计工具。 它将帮助您学习Rust的方式,并且可以捕获许多您可能不会注意到的常见错误。 对我来说,当我知道解决问题的方法时,clippy很有帮助,但我不知道正确的方法
  • rustfmt是Rust的自以为是的代码格式化程序。 我认为,自以为是的格式化程序是可行的方法。 当所有内容都遵循相同的标准时,就没有关于代码格式的争论。
  • sccache是编译器缓存,它将通过减少编译时间来加快处理速度。 但是,请注意,sccache不适用于RLS,因此您不能在IDE中使用它。

工具:不好

好的,好的,在继续讨论Rust的问题之前,我们都应该承认这是一项正在进行的工作。 Rust工具的发展非常迅速,但是我认为它还有很长的路要走。 我将重点介绍一些需要改进的地方:

  • 编译感觉很慢。 不仅速度很慢,而且我发现我经常不得不重新编译软件包。 我了解这种必要性,但有时还是很烦人。 sccache有帮助,但仍然感觉很慢。 有一些方法可以减轻这种情况,例如使用cargo check代替cargo build
  • RLS使用racer来完成代码,而我发现它充其量还是充其量(至少在VSCode中是这样)。 通常,我希望为其完成的功能不存在,而不存在的功能会显示为完成选项。 我尚未进行详尽的分析,但是这些建议似乎只有大约75%的时间是正确的。 其原因可能仅仅是由于RLS的速度较慢。
  • 没有REPL:这可能是不公平的,因为也没有不错的C ++ REPL,但是如今,REPL附带了许多语言。 GitHub上有一个关于此的公开问题 好的REPL不是必需的,但会有所帮助。

工具:丑陋

  • RLS速度慢,越野车和崩溃。 至少对我来说,我发现我经常需要在VSCode中重新启动RLS。 RLS是一个很棒的工具,但充其量确实感觉像是Beta版。 我发现自己不得不暂停并等待RLS赶上来,这样我才能确保自己没有编写不好的代码。 有时候,我认为最好禁用RLS,编写代码,然后像在旧时代那样在Vim中进行所有编码一样,尝试对其进行编译。 就像RLS变得太多了拐杖一样,分心了。

图书馆:好

  • Rust生态系统中大量可用的库令人惊讶。 似乎有一种淘金热来耗尽并实现所有Rust库,并使您的名字在Rust历史上永垂不朽。 您可以在crates.io或GitHub上找到大部分期望的内容。 每次搜索都会为我要找的东西提供2或3种不同的实现方式时,我常常会感到惊讶。
  • 我使用的大多数库都按预期工作,其中许多超出了预期。 这与替代项(它们是不起作用的库)之间有微妙而重要的区别。
1908年,来自国会图书馆的纽约公共图书馆

图书馆:坏人

  • 尽管有很多库,但是我发现它们中有很多是不完整的,不成熟的或完全废弃的。 Rust社区似乎仍处于起步阶段,但它每天都在进步。
  • 有时有太多选择 例如,我想使用一个日志记录库,我发现有一长串可供选择的选项 有很多选择是可以的,但是对于这样的事情,我只想告诉他们使用什么。 Java生态系统在java.util.logging,log4j,logback,log4j2,slf4j和tinylog中也存在类似的问题。 到目前为止,我仍然不知道哪个Java日志记录库是最适合使用的。 对于Rust,我只是决定使用env_logger因为它是列表中的第一个选项。
  • 虽然不如Node.js生态系统那么糟糕,但每个库的依赖项列表已经相当长。 我写了一个名为LabHub的GitHub小型机器人 ,但我仍然惊讶于引入了多少依赖项(181个箱子,如果您想知道的话)。 对我来说,这意味着碎片化和重复,可以通过将一些广泛需要的功能缓慢地移植到标准库中来改进(C ++做得很慢)。

图书馆:丑陋

  • 我注意到,除了一个相对简单的应用程序的大量依赖关系之外,我还多次编译同一库的不同版本。 我认为Cargo为了保持向后兼容性而试图变得聪明。 它基于语义版本来猜测要包括哪些库。 令我担心的是,当您拥有一个依赖于其他也有漏洞的旧库的坏版本的库时,会发生什么。 毫无疑问,Rust的作者已经考虑过这一点,但这似乎仍然很奇怪。 公平地说,处理依赖项的依赖项是一个非常棘手的问题。 值得庆幸的是,有一个适用于Cargo树形工具 ,可以帮助您解决这些问题,然后您可以强制依赖项升级其依赖项。
10个不同的库,在同一软件包中具有2个不同的版本

最后的想法

Rust是一门很棒的语言。 如果您热衷于编程,请尝试一下。 我希望你喜欢它。

我试图想一个

关于我:我从12岁起就一直在编写代码,为许多不同的开源项目做出了贡献,并在Airbnb,Mesosphere和Citadel等多家公司工作。 github.com/brndnmtthws的 GitHub上找到我 ,在 twitch.tv/brndnmtthws的 Twitch 上找到我 ,或在 twitter.com/brndnmtthws的 Twitter上 找到我

From: https://hackernoon.com/programming-in-rust-the-good-the-bad-the-ugly-d06f8d8b7738


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Matlab - 串口通信(转)发布时间:2022-07-18
下一篇:
【Rust日报】 2019-02-15发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap