写点什么

编程界的新星 — Rust 凭什么被业界青睐(内附学习资源)

作者:Greptime
  • 2023-04-28
    美国
  • 本文字数:4439 字

    阅读完需:约 15 分钟

编程界的新星 — Rust 凭什么被业界青睐(内附学习资源)

Rust 语言,作为一门充满活力的计算机编程语言,近年来逐渐成为业界的焦点。在 Stack Overflow 的年度开发者调查报告中,Rust 连续多年被评为“最受喜爱的编程语言”,越来越多的大公司如谷歌、微软、腾讯等都开始将其运用于各类项目中。


尽管 Rust 语言颇受欢迎,我们发现很多学生和初级程序员对它的了解仍显不足。作为一个使用 Rust 语言开发的开源数据库项目团队,我们希望能帮助更多人深入了解这门安全、高效的编程语言。因此,本文将向大家介绍 Rust 的起源、优势,并为有意学习 Rust 语言的朋友们提供一些我们认为还不错的学习资源

Rust 语言是什么

由来

Rust 最初由 Mozilla 的员工 Graydon Hoare 开发,并于 2010 年首次亮相。Rust 的开发团队在 Mozilla 的帮助下,不断改进语言的设计和实现,直到 2015 年 Rust 1.0 正式发布。Rust 的设计灵感来自于 C++、C#、Haskell 和 Erlang 等多种编程语言,具有其它语言所不具备的一些独特特性。作为一门现代系统编程语言,其旨在提供内存安全、高性能和可靠性

Rust 语法

Rust 的语法类似于 C++,它采用了一些现代编程语言的特性,如模式匹配、闭包和迭代器等,同时也继承了 C++ 的语法和底层系统编程能力。而为了解决 C++ 存在的内存安全问题和并发性问题,Rust 引入了一个严格的所有权模型和类型系统,能够在编译期间检测内存错误和数据竞争问题,从而确保程序的安全性和稳定性

Rust 的优势

高性能

Rust 的高性能是指其能够在保持内存安全和语言特性丰富的前提下,提供接近于 C++ 的高性能表现。Rust 的高性能主要得益于其对于内存分配、多线程处理和零成本抽象等方面的优化。


如果把 Rust、C++ 和 Golang 比作三个要参加跑步比赛的运动员:


那么 C++ 无疑是一位经验丰富的选手,他有很高的速度和灵活性。然而,C++ 需要自己负责“调整呼吸和心率”等许多事项(内存管理),这使得他在比赛中容易出错,导致失速或摔倒(内存泄漏、悬垂指针等问题)。


Golang 运动员则是一位新锐选手,其优势在于有一个智能的教练(垃圾回收器)在比赛中为他调整呼吸和心率。虽然这样可以避免很多失误,但是需要不断与教练沟通,这会减慢他的速度。


而 Rust 运动员则是一位全能选手。他借鉴了 C++ 运动员的速度和灵活性,同时又学会了像 Golang 一样在比赛前就制定好详细的计划(所有权、借用和生命周期等机制)。这使得 Rust 运动员在比赛中既能保持高速度,又能避免失误。



上图是 Discord[1] 进行的负载测试,明显可以看到用 Golang 的情况下,每隔一段时间系统就会有一个负载峰值,这就是垃圾回收器在作怪,而改成 Rust 实现之后,整体就平滑很多。同时在 Rust 版本中,延迟、CPU 和内存都要好一些。

可靠性

想象一下 Rust 和其他编程语言(如 C++)是两家餐厅,它们各自的可靠性是如何体现在食物制作过程中的呢?


C++ 餐厅制作食物的过程相对自由。厨师可以随意调整食材、烹饪方法和加工方式。虽然这样的灵活性可能带来很多创新,但在这个过程中,食物容易受到污染,比如厨师在切生鱼片时使用了切生肉的刀具,可能导致食物中毒。这就像 C++ 在处理内存和资源时,它的灵活性可能导致诸如内存泄漏、空指针解引用和数据竞争等问题。


而 Rust 餐厅则更加严格和规范。在制作食物的过程中,Rust 餐厅会对食材的来源、厨师的操作、烹饪方法等进行严格的监管。比如,它会要求在切生鱼片之前,厨师必须先换一把干净的刀具。Rust 餐厅的严格监管确保了食物质量和安全性,减少了因为疏忽而导致的问题。


Rust 在编译阶段通过借用检查器(Borrow Checker)进行内存安全检查,确保在内存操作过程中遵循严格的规范,减少程序运行时的错误,从而提高了整体的代码质量和安全性。


  • 内存安全


Rust 的内存安全优势在于,这些机制会在编译阶段就检查程序的内存管理是否正确,防止程序员在编写代码时犯下诸如内存泄漏、双重释放和悬垂指针等错误


这就像餐厅的管理者预先规划了菜肴的烹饪和清理流程,确保餐厅始终保持卫生和高效。因此,相较于其他编程语言,Rust 更能确保内存安全和程序的稳定性。


我们尝试写点代码看看,下面是一个错误的示例:


fn main() {    let r;
{ let x = 5; r = &x; }
println!("r: {}", r);}
复制代码


在上述这段代码中,我们在外部作用域中定义了一个 r。在内部作用域中,定义了 x, 并把 x 的引用赋值给了 r,最后我们在外部作用域中访问了 r


我们尝试编译下上述代码,Rust 编译器会给出详细的错误信息。如下所示:


error[E0597]: `x` does not live long enough --> src/main.rs:6:13  |5 |         let x = 5;  |             - binding `x` declared here6 |         r = &x;  |             ^^ borrowed value does not live long enough7 |     }  |     - `x` dropped here while still borrowed8 |9 |     println!("r: {}", r);  |                       - borrow later used here
For more information about this error, try `rustc --explain E0597`.error: could not compile `safe_memory` (bin "safe_memory") due to previous error
复制代码


那为什么是错误的?


上面的 报错信息就已经很详细了,我们复述一下。因为变量 x 并没有 “存在的足够久”。当 x 到达第七行时,就离开了作用域,会被 drop 掉,此时外部作用域的 r 就变成了悬垂引用,所以在第 9 行访问 r 时,就会报错。


如果去掉第九行的话,编译就会通过。因为编译器知道在 x 被 drop 之后 ,没有地方可以再访问到悬垂引用 r 了。


小结一下:Rust 的一个重要特性是内存安全。Rust 编译器在编译期间会检查程序中的内存安全问题,并尽可能让这些问题在编译期暴露出来,从而避免运行时出现内存错误。


  • 并发安全


Rust 的并发安全是指其能够在多线程环境下保证线程安全,避免出现数据竞争和死锁等问题。Rust 的并发安全主要依靠其所有权、借用机制及生命周期,当一个值被多个线程引用时,Rust 会阻止这些线程同时访问这个值的可变引用,从而避免了数据竞争问题。


下面这个 demo 演示了如何使用 Rust 中的原子类型来实现一个线程安全的累加器。


use std::sync::{    atomic::{AtomicI32, Ordering},    Arc,};
fn main() { let counter = Arc::new(AtomicI32::new(0)); let mut handles = vec![];
for _ in 0..10 { let counter = counter.clone(); let handle = std::thread::spawn(move || { for _ in 0..1000 { counter.fetch_add(1, Ordering::Relaxed); } }); handles.push(handle); }
for handle in handles { handle.join().unwrap(); } // the result should be 10*1000=10000 println!("Counter value: {}", counter.load(Ordering::Relaxed));}
复制代码

Rust 生态

Rust 语言虽然没有 JAVA、C++ 那么成熟,但近年来它周边的生态系统也在不断发展,已经拥有了很多库和框架。一些 Rust 周边生态中的主要部分有:


  • 包管理器:Cargo[2] 是 Rust 的官方包管理器,用于构建、测试、发布 Rust 应用程序和库。

  • Web 开发:Actix[3] 和 Rocket[4] 是 Rust 中最受欢迎的 Web 框架,提供了构建高性能、安全的 Web 应用程序所需的功能。

  • 异步编程:Tokio[5] 和 async-std 是 Rust 中用于异步编程的两个主要库,提供了异步 I/O,定时器和任务调度等功能。

  • 操作系统开发:Rust 在操作系统开发方面也具有潜力,Redox[6] 是一个用 Rust 编写的微内核操作系统,代表了 Rust 在系统编程领域的实力。


这只是 Rust 生态系统中的一部分。随着 Rust 社区的不断发展,可以期待更多的库和框架会出现。

Rust 学习渠道

以下书籍涵盖了从基础到高级的 Rust 知识,适合不同水平的读者阅读。


入门:


  • The Rust Programming Language

  • Programming Rust


中级:


  • Rust for Rustaceans

  • Rust Atomics and Locks

  • The Rust Reference


高级:


  • The Rustonomicon


当然也可以看 Rust 专家的视频讲解,比如:


  • Jon Gjengset(youtube.com/c/jongjengset),这是一位讲解 Rust 语言的博主,同时他也是麻省理工学院的教授,他的视频内容会更加进阶,适合已经有一定 Rust 语言基础的受众。


入门之后,还可以通过一些练手项目更深入地学习和使用 Rust,比如:


  • Tokio,一个异步的运行时用于编写高性能的网络应用程序

  • Serde[7],一个用于序列化和反序列化 Rust 数据结构的库。

  • Diese[8],一个 Rust 的 ORM(对象关系映射)库,用于将 Rust 数据结构映射到关系型数据库中


这些项目都可以帮你在 Rust 的使用方面更加精进。


当然,你也可以选择我们的 GreptimeDB[9] 项目进行练习,GreptimeDB 是用 Rust 语言编写的开源时序数据库项目。我们提供了一系列适合新手的 good first issues,欢迎到 GitHub 上查看详情。

总结

在 1.0 发布前,Rust 断舍离了内部的 green threads 实现,彻底坚定了这门语言作为一个无运行时、低抽象层级的设定。即便是之后标准库引入了异步 Future API,这一特色仍然保持。


低抽象级别带来的更细更强的控制力,使得 Rust 开发者可以更精准地控制资源(线程、内存),非常适合诸如服务器、数据库等场景的开发,直接对标 C++ 的传统领域。但控制力的背面是高风险,C++ 因其风险性广受诟病,也促使 Mozilla 选择尝试新语言。与之前 20 年中诸如 Java 、Go 等通过牺牲控制力降低风险的解决方案不同,Rust 选择用编写和编译时的强限制,比如让人又爱又恨的 borrow checker 和 lifetime ,保全了运行时的高性能和安全性


当然,代价是相对陡峭的学习曲线和较长的编译时间。在这方面,Rust 在早期就成立了工具团队,持续在用更好的开发工具来降低其负面影响。

参考

[1] https://discord.com/blog/why-discord-is-switching-from-go-to-rust


[2] https://doc.rust-lang.org/cargo/


[3] https://actix.rs/


[4] https://rocket.rs/


[5] https://github.com/tokio-rs/tokio


[6] https://www.redox-os.org/


[7] https://github.com/serde-rs/serde


[8] https://github.com/diesel-rs/diesel


[9] https://github.com/GreptimeTeam/greptimedb




关于 Greptime

Greptime 格睿科技于 2022 年创立,目前正在完善和打造时序数据库 GreptimeDB 和格睿云 GreptimeCloud 这两款产品。

GreptimeDB 是款用 Rust 语言编写的时序数据库。具有分布式,开源,云原生,兼容性强等特点,帮助企业实时读写、处理和分析时序数据的同时,降低长期存储的成本。

GreptimeCloud 基于开源的 GreptimeDB,为用户提供全托管的 DBaaS,以及与可观测性、物联网等领域结合的应用产品。利用云提供软件和服务,可以达到快速的自助开通和交付,标准化的运维支持,和更好的资源弹性。GreptimeCloud 已正式开放内测,欢迎关注公众号或官网了解最新动态!

官网:https://greptime.com/

公众号:GreptimeDB

GitHub: https://github.com/GreptimeTeam/greptimedb

文档:https://docs.greptime.com/

Twitter: https://twitter.com/Greptime

Slack: https://greptime.com/slack

LinkedIn: https://www.linkedin.com/company/greptime/


用户头像

Greptime

关注

专注于 Infra 技术分享 2022-09-23 加入

分布式、高性能、存储计算分离的开源云原生时序数据库

评论

发布
暂无评论
编程界的新星 — Rust 凭什么被业界青睐(内附学习资源)_rust_Greptime_InfoQ写作社区