极客油画

目前来看,只有rust可以拯救linux的桌面开发。

rust 和 linux

linus torvalds原话:

我们拭目以待。我不认为 Rust 会接管核心内核,但在其中开发单个驱动程序(甚至可能是整个驱动程序子系统)听起来并非完全不可能。也许文件系统也是如此。因此,这并不是 “取代 C”,而是 “在有意义的地方增强我们的 C 代码”。

当然,驱动程序大约占实际内核代码的一半,因此有很大的空间。但我不认为有人真的期望用 Rust 全面重写现有的驱动程序,更多的是 “有些人会用 Rust 做新的驱动程序,并且一些驱动程序可能会在有意义的地方被重写”。

rust 和 c

rust完美继承了c语言精确高效的特性,但是又同时避免了像c++那么庞大。

在rust语言里面,其实住着一个完整的c语言,它跟c是完全兼容的,比如说c语言写的动态链接库,是可以直接在rust语言里面直接调用的,并且没有性能损耗。

rust语言也可以用来写动态链接库,然后在c语言里面无性能损失的去调用这个动态链接库。

rust可以写跨平台的可移植的底层库,然后供其他语言调用,因为其他语言都兼容C接口。

但是rust语言和c++语言之间就没有这么好的兼容性了。

trait是rust的灵魂

trait 用一种方法论把整个rust语言划分成一块一块小的领地,包括所有权、移动语义、复制语义、对象的回收、不同类型之间的转换,这些都可以用trait来定义。

运算符重载,在c++里面是语言固有的一个特性,但是在rust语言里面,它是归类到这个trait下面的,比如说要重载这个加号,它有个trait叫做Add,你只需要对类型实现Add这个trait就行了。

这就意味着运算符重载就不是一个顶层的语言内置特性,它只是一个具体的trait而已。

trait有个特点,它是非侵入性的,不需要改原有这个结构体的内容,它可以直接在这个类型上私加一个新的trait,这样的话,那个类型就具有了那个trait提供的那些方法。

这个非侵入性的方法,不能乱用,它遵循这个“孤儿规则”。

Rust 不会重蹈 C++ 特性膨胀的覆辙

C++ 的特性膨胀主要源于几个历史原因:

  • 兼容性包袱:​​ 必须几乎 100% 向后兼容 C 和旧版本的 C++。
  • 范式叠加:​​ 从 C 的面向过程,到加入面向对象,再到泛型、函数式、元编程等,是典型的“加法”模式,新旧范式并存。
  • 委员会设计:​​ 由多个利益相关的厂商组成的委员会决策,有时为了达成一致,会引入复杂或重叠的特性。
  • 缺乏内存安全等核心抽象:​​ 很多特性是为了“兜底”或绕过语言本身的限制(如预处理器、模板元编程),导致复杂性激增。

Rust 从设计之初就没有考虑兼容c的语法,并建立了严格的机制:

  1. 强大的核心抽象:从根源减少特性需求

Rust 的所有权系统和特质系统是其强大的核心抽象,许多在 C++ 中需要特殊特性来解决的问题,在 Rust 中可以用更统一的方式解决。

  • 例子:移动语义​​:在 C++11 中,这是一个巨大且复杂的附加特性。而在 Rust 中,​​移动是默认行为​​,是所有权系统与生俱来的一部分,非常简单直观。
  • 例子:资源管理​​:C++ 需要 RAII 原则+智能指针来手动管理。Rust 的所有权系统在语言层面自动且强制地实现了这一点,无需额外特性。
  • 例子:泛型​​:Rust 的泛型与特质紧密结合,比 C++ 模板更类型安全,同时也通过特化等机制避免了一些 C++ 模板元编程的复杂性。
  1. 严格的 RFC 流程和语言设计原则

每个新特性都必须经过 ​​RFC​​ 流程,接受整个社区的严格审查。审查时会问一些关键问题:

  • 是否绝对必要?​​ 这个功能能解决多少现有代码无法解决或解决起来很痛苦的问题?
  • ​​是否与语言核心哲学一致?​​ 是否符合“零成本抽象”、内存安全、并发安全的原则?
  • 是否正交?​​ 新特性是否与现有特性协调工作,而不是重叠或矛盾?
  • ​​是否教与学友好?​​ 会不会显著增加语言的学习曲线?(Rust 团队对可学性有明确的承诺)

这个过程筛掉了很多“听起来不错但非必需”的特性。

  1. 偏好通过库而非语言特性来实现功能

Rust 极力倡导“将语言内核保持精简”。很多功能会优先考虑在标准库中实现,或者更理想的是,在第三方库中实现。只有当库解决方案性能不佳或无法表达时,才会考虑加入语言特性。

  • 成功的例子:​​ Vec, HashMap等集合是在标准库中实现的,而非语言关键字。
  • 异步编程的例子:​​ async/await最终成为了语言特性,因为经过长期实践,发现仅靠库无法实现零成本抽象和良好的用户体验。
  1. 版本化和限定范围

通过 Edition 系统,Rust 可以在不破坏现有代码的情况下,引入一些不兼容的语法改进和新惯用法。这允许语言进行“内部清理”,避免为了兼容而保留过多过时的语法糖,从而在一定程度上控制膨胀。

rust的Edition 系统

在没有 Edition 系统的情况下,语言演进会面临一个两难困境:

  • 永远不引入破坏性更改:​​ 这会导致语言停滞,无法修复设计错误或引入更优雅的语法。
  • 引入破坏性更改:​​ 这会迫使所有开发者更新他们的代码库,否则就会在升级编译器后无法编译,这正是很多语言(包括 C++ 在某些方面)面临的问题。

Rust 的 Edition 系统提供了第三条路:​​在绝大多数情况下保持严格的向后兼容,同时允许在特定的、有版本标识的边界内进行不兼容的改进。​

Edition 的变更通常是​​增加性的和选择性的​​,主要集中在:

  • 引入新的关键字:​​ 例如,async, await, try这些词在旧 Edition 中可能不是关键字,可以作为变量名。在新 Edition 中,它们变成了关键字,不能再用于变量名。这种变化是“破坏性”的,但通过 Edition 来限定范围。
  • 引入新的语法:​​ 例如,2018 Edition 引入了更简洁的模块路径语法(use std::path::{Path, PathBuf};而不是某些复杂的 macro_use形式)。
  • ​​改变默认行为:​​ 例如,2021 Edition 中,闭包捕获规则变得更加智能,只捕获它们实际使用的字段,而不是整个结构体。
  • 推广新的惯用法:​​ 鼓励使用新的、更好的写法来替代旧的模式。

如何在项目中使用和配置 Edition?在你的 Cargo.toml文件中,可以通过 edition字段来指定:

[package]
name = "my_project"
version = "0.1.0"
edition = "2021" # 可以是 "2015", "2018", "2021"

如何迁移到新 Edition?Rust 提供了强大的工具 cargo fix来帮助你自动将代码从旧 Edition 迁移到新 Edition。

# 在项目根目录下,先将 edition 值改为 "2021",然后运行:
cargo fix --edition
# 或者更安全的做法,先检查会修复什么:
cargo fix --edition --dry-run

工具

2D绘图工具: https://github.com/GraphiteEditor/Graphite

3D绘图工具: https://github.com/blender/blender


本文发表于 0001-01-01,最后修改于 0001-01-01。

本站永久域名「 jiavvc.top 」,也可搜索「 极客油画 」找到我。


上一篇 « 下一篇 »

赞赏支持

请我吃鸡腿 =^_^=

i ysf

云闪付

i wechat

微信

推荐阅读

Big Image