0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Rustacean原则概要

倩倩 来源:Rust语言中文社区 作者:Rust语言中文社区 2022-09-21 11:29 次阅读

也许这篇文章可以消除你对 Rust 的诸多误解。

背景

Rustacean 是对Rust 编程语言[1]的用户的称呼。所以,「Rustacean 原则」可以看作是 Rust 官方团队站在 Rust 语言用户角度上创造 Rust 语言时所参考的原则。

Rustacean 是 Rust +‎ crustacean 的混合词。crustacean 是指甲壳纲动物,所以 Rust 社区将螃蟹作为 Rust 语言的吉祥物,称之为 Ferris,中文叫摩天蟹。值得明确的是,该吉祥物并非 Rust 官方指定的,最初由 Karen 在 rustacean.net[2] 网站公布了 Ferris 的概念艺术图。

Rustacean 原则是由 Rust 语言团队 Leader Niko 在 2021 年所发起的项目[3],这个项目试图列举支配 Rust 设计和社区运作方式的原则。Niko 说,这些原则并非代表 Rust 官方而发布,只是他自己的观点。建立原则的重点在于尝试更好地发展原则并且在团队中使用。

虽然这些是实验性原则,但该原则在 Rust 官方内部经过一致性的讨论和认可。从 Niko 今天发布的最新博客Rust 异步trait Part8[4] 和 谈 “Rust 之魂”[5] 中也看得出来,该原则应该已经在使用了。

去年的时候,因为 Niko 这篇 Rust 原则的文章还引发了社区的一些争议。(前)Rust 核心团队成员 Steve Klabnik 认为 Niko 这篇原则是以亚马逊原则为蓝本的,所以暗示亚马逊在某种程度上对Rust的开发负责。亚马逊雇佣了多名Rust维护者和贡献者,但它只是众多有员工参与的公司之一。Rust库团队负责人Mara Bos的观点却与之相反,她认为Steve的观点“简直是胡说八道”。事情经过一年回头再看原则的这些内容,其实也没有 Steve Klabnik 说的那么离谱,Rust 原则的内容确实对 Rust Project 开发和贡献有指导作用,让大家知道力往哪里使。

今天打算写这篇文章,和读者朋友们一起学习一下 Rust 语言创造过程背后所遵循的原则,进一步理解 Rust 的设计哲学。值得说明的是,Rustacean 原则的大部分详细内容 Niko 并没有写完,所以这里有很多细节内容是由我来补充的。

Rustacean 原则概要

Rustacean 原则主要分为两部分内容:

Rust 语言如何为用户赋能,代表 Rust 和 用户的契约

Rust 社区如何治理才能更贴近 Rustacean ,代表Rust 团队成员和贡献者之间的一种“契约”。

这份原则总的来说,是为 Rust 的总体目标服务的。Rust 的总体目标是:成为一门赋予每个人构建可靠且高效软件能力的语言。

Rust 如何为用户赋能

这部分原则内容包括:

可靠性( Reliable)。如果它编译,它就可以工作。

高性能( Performant)。既高效执行又使用最少内存。

支持性( Supportive)。语言、工具和社区随时为用户提供帮助。

生产力( Productive)。让工作事半功倍。

透明性( Transparent)。让用户可以预测和控制底层细节。

多样性( Versatile)。你可以用 Rust 做任何事。

Niko 所说的 “Rust 之魂”正是指 Rust 团队在这几个关键原则之间的斗争——尤其是生产力、多样性与透明性之间的权衡。

可靠性

具体而言,可靠性意味着要保证安全的 Rust 代码可以避免未定义行为。类型安全是可靠性的关键要素。类型安全不是一种口头建议,而是靠编译器来管理。但是类型安全会增加语言的复杂性,让 Rust 的学习变得更加困难。为此,Rust 团队在错误信息和文档上非常努力,以便减轻这种复杂性带来的学习成本。正是因为这些成本,Rust 团队才对Rust的类型系统试图实现的东西施加了一些限制。

比如,对某些类型的错误条件采用了运行时检查。并不试图证明索引在范围内,而是检查像vec[i]这样的表达式,以确保i < vec.len()。在编译时证明 i< vec.len() 会增加类型系统的复杂性,所以团队选择不这么做,尽管这样会损失一些可靠性,但是增加了生产力。

再比如,允许用户使用 Unsafe 代码逃离类型系统的复杂性。比如,Safe Rust 不能表达双向链表,但可以用 Unsafe Rust 来实现。然而,也希望用户能够封装(安全抽象)他们的 Unsafe 代码,向整个世界展示一个安全的界面。这与 Unsafe 代码作者的生产力感觉相悖(考虑如何封装东西更复杂),但对世界其他地方的可靠性却有很大好处。

另一方面,Rust不隐藏错误条件,并鼓励明确列出所有的可能性(或承认某些东西被忽略)。比如,Rust 要求用户提供详尽的 match 匹配分支,逼迫用户去考虑所有情况。这样做有助于提升 Rust 代码的可靠性,但这是以降低用户的生产力为代价的。所以,这是一个权衡。

错误处理就是一个很好的权衡案例。编程语言历史长久以来,错误处理一般是使用异常。异常处理对用户而言,提升了生产力。但是异常隐藏了控制流,用户很难进行推理,在实践中充满了问题,对可靠性极大的不利。而Rust采用了函数式语言中首创的返回枚举的方法,让用户强制考虑错误处理的方式,这有助于可靠性。其后又引入了?操作符,让用户更方便地传播错误,是生产力的提升,同时确保错误路径对用户来说仍然是可见的,不会被完全忽略。

高性能

Rust 借鉴了 C++ 社区的零成本抽象概念。Cpp 之父 Bjarne 将零成本抽象定义为:“What you don't use, you don't pay for. And further: What you do use, you couldn't hand code any better”。零成本抽象意味着,用户可以使用语言提供的高级抽象能力编写代码,而编译器则会通过优化为开发者生成高性能的代码,进一步来说,就是将多余无用的代码优化掉,将有用的代码优化得更加高效。

dd53e73a-395c-11ed-9e49-dac502259ad0.png

(图片来自于 2021 年Rust Dublin的轻talk: Zero Cost Abstractions[6])

这份性能测试并非要踩 C#/Java 语言,只是为了突出 Rust 的零成本抽象能力的性能。你可以看到,Rust 提供了非常优雅且和Java/C# 等同的高级迭代器抽象,而不会影响代码的性能。

这也是被很多人误会的一点,他们认为 Rust 宣传的零成本抽象是百分之百的。但实际上想要保证百分之百零成本抽象是非常困难的,Rust 在这一方面也充满了权衡。

Rust 的开发者认为,零成本抽象,不仅仅是追求零成本和最佳性能,还更应该着重改善用户体验,因为这就是抽象的意义所在。Rust 语言中的达到这个标准的零成本抽象特性只有少数的几个,这些由 withoutboats 在他的博客中[7]列了出来:

Rust 所有权和借用机制。在没有垃圾收集器的情况下保证内存和线程安全是 Rust 最初的巨大成功故事。

迭代器和闭包 API。这是另一个经典特性。就像上图中所示的迭代器代码一样,你可以优雅地使用各种过滤器、map和for循环,优化出来的代码和手写的高效 C 代码等价。

Async/Await 和 Future。Futures API 是一个重要的例子。早期的 Futures (指 0.3 版本之前)很好地达到了“零成本”的标准,但是没有提供足够好的用户体验。后来通过添加 Pin 来支持跨 await 的引用等,才达到一个用户体验良好的零成本抽象。

Unsafe Rust 和 模块边界(可见性)。这是 Rust 其他零成本抽象之母,因为这是 Safe Rust 的基础。

除此之外的其他特性则没有取得太大的成功,这有些例子:

trait 动态分发,目前没有找到成功的解决方案。

泛型的trait限定,对优化有一定阻碍,所以才引入了 特化(Specialization)。

NewType 模式,在某些情况下优化并不理想(详细可参考延伸阅读reddit相关内容)。

为什么百分百的零成本抽象这么难?因为 Rust 要考虑的因素太多。除了要为用户提供体验良好的抽象之外,还要对透明性和多样性做权衡,这些都是对编译器优化干扰的因素。

很多人对 Rust 的另一个误解就是,用 Rust 实现的代码性能一定很好。但是实践结果很有可能打破他们这层认知。开发者在使用 Rust 代码的时候需要注意考虑以下几个问题:

你的抽象有多少成本

你的代码热点路径在哪(调用频繁的代码),该如何优化

利用好性能基准测试

因为 Rust 零成本抽象并不保证用户写的 Rust 代码性能最佳。

支持性

Rust 工具致力于为开发人员提供优美、流畅的体验。一个例子是编译器如何提供高质量的错误消息,这些消息不仅试图指示错误,而且还教用户 Rust 语言是如何工作的,并就如何修复他们的代码提供有用的建议。最近 Rust 官方还启动了诊断信息多语言翻译计划,欢迎大家去贡献。

对于像 cargo 这样的工具,这体现在精心的 CLI 设计中,使“简单的事情变得简单”。基于 Cargo 的有用的第三方插件变得越来越丰富。

生产力

生产力可能会与可靠性、高性能有冲突,所以这里也存在权衡。可以参考上面列举出来的 Rust 零成本抽象成功的几个特性,比如所有权机制。很多人认为所有权机制影响生产力,是因为这种安全内存管理方式比较新颖,接受起来没有那么快。但是换成 GC 语言,开发者就没有这个心智负担,生产力自然提升。但熟练使用 Rust 的开发者则不会受这个影响。

让 Rust 变得极具生产力的方法是什么?

Rust 致力于跨版本的稳定性。这是因为稳定性是生产力的关键推动因素:如果没有跨版本的稳定性,用户将被迫花时间解决构建失败,而不是构建用户想要构建的功能。但是这种稳定性也会阻碍 Rust 语言开发者们对语言特性设计的自由度,所以引入了 Edition 系统让设计自由度和语言版本稳定性达到平衡。

可移植性。默认情况下,Rust 代码旨在跨所有主流架构移植。

打造繁荣的生态系统。

透明性

Rust 官方团队非常重视透明性。透明性是 Rust 提供给用户的底层掌控力,但需要注意并不意味着它能帮用户自动提升性能。

但透明性暴露的底层控制细节,让多样性和生产力大打折扣。比如 repr属性,再比如异步函数中随处可见的 Box>>。因为它会迫使用户过度关注对当前要解决问题实际并不重要的底层细节。

透明性与多样性、生产力有所冲突,在设计语言特性时需要仔细权衡。

多样性

Rust 同样重视多样性,多样性意味着通用性,意味着 Rust 可以做上层的应用,也可以做底层的系统开发。

官方的目标是以某种方式向 Rust 程序公开所有核心系统功能,即使访问或正确使用它们可能很困难。而不希望 Rust 用户觉得他们必须选择 C 或其他语言,他们应该能够使用 Unsafe Rust 来完成他们的工作。像“内联汇编”这样的功能也遵循这种思路。

我能想到一个比较典型的例子是,Rust 将 Error trait 移动到了 core 中,这样就可以统一 std 和 no_std 的错误处理了。

Rust 社区如何治理才能更贴近 Rustacean

该部分内容提供了以下一些原则,用于帮助 Rust 核心团队和社区贡献者良好合作:

善良体贴。相互尊重彼此才是构建 Rust 未来的基础。

给用户带来快乐。首要目标是让 Rust 用户更有效率和能力。希望人们喜欢使用 Rust,如果他们愿意,也喜欢参与它的社区。

畅所欲言地表达自己。带上你的专业知识,并愿意为你认为正确的事情进行辩论。

认可别人的知识。没有人能垄断好的创意。Rust 团队需要汲取优秀的建议来改进设计。

从小处开始。寻找完美的设计需要迭代。大处着眼,小处着手;当你了解更多时,不要害怕改变。

跟进。说你会做的,做你说的。

把爱传出去。Rust项目成员需要识别有潜力的贡献者,有义务去发展新的成员,并且当好教练的角色。

信任和委托。赋予他人权力意味着愿意让他们以他们认为最好的方式做出决定。

P.S 金发姑娘原则

在 Niko 的博客中还提到一个金发姑娘原则(Goldilocks),比较有趣。

该原则出自一个英国的童话故事《金发姑娘和三只熊》。

讲的是一位金发姑娘偷偷跑进熊的家里,她发现了三碗粥、三把椅子和三张床,粥有冷的、有热的;椅子有硬的、有软的;床有大的、有小的。她都尝了、都试了以后,选择了不冷不热的那碗粥,不硬不软的那把椅子,不大不小的那张床,因为那碗粥、那把椅子、那张床最适合她,对她来说都是“刚刚好”,这种选择的原则就叫做“金发姑娘原则”。

“金发姑娘原则”被应用在各个领域,比如发展心理学、经济学、通讯科学、医学和天体生物学、沟通等等。

如果把该原则用在如何看待(新)事物方面,那么它会成为一个非常好的思维工具。通过该原则,可以让你避免用非黑即白的思维看待这个世界存在的事物,比如 Rust 语言,比如某个人。这个世界并不是好与坏、黑与白这两个极端,它还存在中间状态。

小结

本文可能还缺少很多细节,但总体上我认为应该把 Rustacean 原则和 Niko 所说的 Rust 之魂讲清楚了。Rust 语言并不完美,但它在这些原则之间不断权衡而发展。我们可以不完美,也不可能完美,但不能不追求完美。感谢阅读。

审核编辑 :李倩

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编程语言
    +关注

    关注

    10

    文章

    1944

    浏览量

    34726
  • Rust
    +关注

    关注

    1

    文章

    228

    浏览量

    6605

原文标题:Rustacean 原则 与 Rust 之魂

文章出处:【微信号:Rust语言中文社区,微信公众号:Rust语言中文社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    详解SMT工艺的五球原则

    SMT(表面贴装威廉希尔官方网站 )工艺中的五球原则,是工程师在选择焊膏时的一个重要指导原则,它确保了焊接的可靠性和质量。以下是对五球原则的详细解释:
    的头像 发表于 12-04 09:11 153次阅读
    详解SMT工艺的五球<b class='flag-5'>原则</b>

    PCB上设置测试点的基本原则

    线路板PCB测试点设置的原则是确保测试的准确性和高效性,同时避免对PCB板造成不必要的损害。以下是一些关键的设置原则
    的头像 发表于 10-22 10:57 684次阅读

    差动保护动作电流整定原则

    差动保护动作电流整定原则涉及多个方面,以下是对该原则的介绍: 一、基本原则 对称性原则 :差动保护动作电流应该在正、负序电流及零序电流相等时启动。这样差动保护在正常工作时不至于误动作,
    的头像 发表于 10-08 15:45 926次阅读

    放大线路的组成原则是什么

    放大电路的组成原则涉及电子元件的选择、电路的设计以及信号的放大机制等多个方面。以下是放大电路的主要组成原则: 1. 直流电源设置 原则描述 :必须根据所用放大管的类型提供直流电源,以便设置合适的静态
    的头像 发表于 09-23 10:58 368次阅读

    安全型继电器要符合什么原则

    安全型继电器在设计和使用过程中,必须符合的核心原则是 故障-安全原则 。这一原则的具体含义和要求可以归纳如下: 故障-安全原则 定义 :当继电器或相关系统发生故障时,应能自动导向或转换
    的头像 发表于 09-21 10:12 560次阅读

    PGA309正常只校准一个温度点大概要多久时间呢?

    目前我采用的PGA309USB-EVM单个校准压力传感器,我只校准一个常温25摄氏度的温度,我发现校准的时候全部过程都要跑一遍,这样时间需要花费几分钟(不需要等温度达到25 的时间),请问正常只校准一个温度点大概要多久时间呢?盼回复。感谢!
    发表于 08-16 07:13

    组成放大电路的基本原则是什么?

    组成放大电路的基本原则主要包括以下几个方面: 1. 稳定性原则 定义 :稳定性是指放大电路在工作过程中应能够保持其性能不受外界干扰或内部变化的影响。 实现方式 :通过采取一些措施来保持电路的工作点
    的头像 发表于 08-07 10:02 739次阅读

    浪涌保护器配置原则及william hill官网

    。正确配置浪涌保护器不仅能有效提高系统的安全性和可靠性,还能延长设备的使用寿命。本文将详细探讨浪涌保护器的配置原则,并结合不同的环境和行业需求,提供相应的配置指导。 一、浪涌保护器配置原则 1.1 选型原则 电压等级匹配: 浪涌
    的头像 发表于 07-17 10:39 431次阅读
    浪涌保护器配置<b class='flag-5'>原则</b>及william hill官网

    工业控制网络的集成原则是什么

    引言 工业控制网络是现代工业生产的核心,它负责实现设备的监控、控制和管理。随着工业4.0的推进,工业控制网络的集成变得越来越重要。本文将详细介绍工业控制网络集成的原则和方法,以确保网络的稳定性
    的头像 发表于 06-11 10:41 534次阅读

    数控加工工艺处理的原则和步骤是什么

    数控加工工艺处理是数控机床加工过程中非常重要的一环,它直接关系到加工质量、生产效率和成本。本文将详细介绍数控加工工艺处理的原则和步骤。 一、数控加工工艺处理的原则 保证加工精度和质量 数控加工工艺
    的头像 发表于 06-07 10:24 970次阅读

    pcb设计的基本原则分享 PCB设计16个原则一定要知道

    PCB设计的这16个原则你一定要知道
    的头像 发表于 03-12 11:19 2870次阅读

    电源变压器的设计原则

    电源变压器的设计原则  电源变压器是电力系统中非常重要的设备之一,它起到将交流电压转换为需要的电压或者将直流电压变换为需要的电压的作用。在设计电源变压器的过程中,需要遵循一些原则和注意事项,以确保
    的头像 发表于 02-02 09:31 1779次阅读

    群脉冲预防方案的基本原则

    群脉冲预防方案的基本原则?|深圳比创达电子
    的头像 发表于 01-15 14:03 611次阅读
    群脉冲预防方案的基本<b class='flag-5'>原则</b>?

    MA35D1 buildroot编译大概要多长时间?

    请问一下,buildroot编译大概要多长时间? yocto编译大概要多长时间?
    发表于 01-15 06:17

    贴片电感选型原则

    电子发烧友网站提供《贴片电感选型原则.docx》资料免费下载
    发表于 12-28 09:15 6次下载