一、简介
编程语言对外展现出来的能力是语言 + 生态的一个合集。所以说一门编程语言的能力,语言本身的设计占了四成,围绕着语言打造的生态系统占了六成,生态可以弥补语言的劣势。
那么,Rust 的生态是什么样子呢? 我们可以用 Rust 做些什么事情呢? 为什么说 Rust 生 态系统已经不错,且潜力无穷、后劲很足呢?
主要从以下这几个方面进行介绍:
- 基础库
- Web和Web开发
- 客户端开发(GUI)
- 云原生开发
- WebAssembly开发
- 嵌入式开发
- 机器学习开发
- 音频处理
- 视频处理
- 图形图像
- …
二、展开介绍
1、基础库
按照重要程度依次简单说一下,方便根据需要自行跳转:
- 序列化和反序列化工具 serde
- 网络和高性能 I/O 库 tokio
- 用于错误处理的 thiserror 和 anyhow
- 用于命令行 处理的 clap/structopt/dialoguer/indicatif等
- 用于处理异步的 futures 和 async-trait
- 用于提供并发相关的数据结构和算法的 crossbeam
- 以及用于撰写解析器的 nom/pest/combine等
- 音频处理creek/cpal/Symphonia/dasp等
- 视频处理rsmpeg/gstreamer/rav1e等
- 图形图像rust-gpu/WGpu等
- …
1.1、serde
每一个从其他语言转移到 Rust 的开发者,都会惊叹于 serde 及其周边库的强大能力。 只消在数据结构上使用 #[derive(Serialize, Deserialize)] 宏,你的数据结构就能够被序列 化和反序列化成绝大多数格式: JSON / YAML / TOML / MsgPack / CSV / Bincode 等等。
你还可以为自己的格式撰写对 serde 的支持,比如使用 DynamoDB,你可以用 serde_dynamo。如果你用过其它语言的 ORM,那么,你可以把 serde 理解成增强版的、普适性的 ORM, 它可以把任意可序列化的数据结构,序列化成任意格式,或者从任意格式中反序列化。
那么什么不是“可序列化的数据结构”呢? 很简单,任何状态无法简单重建的数据结构, 比如一个 TcpStream、一个文件描述符、一个 Mutex,是不可序列化的,而一个 HashMap<String, Vec<u8>>
是可序列化的。
1.2、tokio
如果你要用 Rust 处理高性能网络,那么 tokio 以及 tokio 的周边库,不能不了解。
tokio 在 Rust 中的地位,相当于 Golang 处理并发的运行时,只不过 Golang 的开发者没得选用不用运行时,而 Rust 开发者可以不用任何运行时,或者在需要的时候有选择地引入 tokio / async-std / smol 等。
在所有这些运行时中,最通用使用最广的是 tokio,围绕着它有: tonic / axum / tokio-uring / tokio-rustls / tokio-stream / tokio-util 等网络和异步 IO 库,以及 bytes / tracing / prost / mio / slab 等
1.3、thiserror/anyhow
错误处理的两个库 thiserror / anyhow 建议掌握,目前 Rust 生态里它们是最主流的错误 处理工具。
1.4、clap/structopt/dialoguer/indicatif
clap 和 structopt 依旧是 Rust 命令行处理的主要选择,其中 clap 3 已经整合了 structopt,所以,一旦它发布正式版本,structopt 的用户可以放心切换过去。
如果你要做交互式的命令行,dialoguer 是一个不错的选择。如果你希望在命令行中还 能提供友好的进度条,试试 indicatif。
1.5、futures/async-trait
标准库中已经采纳了 futures 库的 Future trait,并通过 async/await 关键字,使异步处理 成为语言的一部分。然而,futures 库中还有很多其它重要的 trait 和数据结构,比如 Stream / Sink。futures 库还自带一个简单的 executor,可以在测试时取代 tokio。
async-trait 库顾名思义,就是为了解决 Rust 目前还不支持在 trait 中带有 async fn 的问 题。
1.6、crossbeam
crossbeam 是 Rust 下一个非常优秀的处理并发,以及和并发相关的数据结构的库。当 你需要撰写自己的调度器时,可以考虑使用 deque,当你需要性能更好的 MPMC
channel 时,可以使用 channel,当你需要一个 epoch-based GC 时,可以使用 epoch。
1.7、nom/pest/combine
这三者都是非常优秀的 parser 库,可以用来撰写高效的解析器。
1.8、音频处理
在音频处理方面:creek,用于音频的实时磁盘流 IO;Symphonia,纯 Rust 多媒体格式解复用、标签读取和音频解码库;cpal,跨平台音频 I/O 库;dasp,用于数字音频信号处理
1.9、视频处理
在视频处理方面:rsmpeg,字节开源的安全FFmpeg绑定库;gstreamer,GStreamer的Rust绑定库;rav1e,最快最安全的AV1编码器;xiu,简单安全的实时媒体服务器;
1.10、GPU图形渲染
在GPU图形渲染方面也有一些值的关注的开源项目,如图形渲染引擎:rust-gpu,致力于让Rust中图形编程变得简单、快速、可靠的WGpu等。
2、Web和Web开发
虽然 Rust 相对很多语言要年轻很多,但 Rust 下 Web 开发工具厮杀的惨烈程度一点也不 亚于 Golang / Python 等更成熟的语言。主要从以下几个方面介绍:
- Web 协议支持
- Web 框架
- 数据库支持
- 模板引擎
- Web 前端
- Web 测试
- 云平台部署
- 静态网站生成
2.1、 Web 协议支持
从 Web 协议支持的角度看,Rust 有 hyper 处理 http1/http2, quinn / quiche 处理 QUIC/http3, tonic 处理 gRPC,以及 tungstenite / tokio-tungstenite 处 理 websocket。
从协议序列化 / 反序列化的角度看,Rust 有 avro-rs 处理 apache avro,capnp 处 理 Cap’n Proto,prost 处理 protobuf,flatbuffers 处理 google flatbuffers, thrift 处理 apache thrift,以及 serde_json 处理我们最熟悉的 JSON。
一般来说,如果你提供 REST / GraphQL API,JSON 是首选的序列化工具,如果你提供二进制协议,没有特殊情况(比如做游戏,倾向于 flatbuffers),建议使用 protobuf。
2.2、Web 框架
从 Web 框架的角度,有号称性能宇宙第一的 actix-web;有简单好用且即将支持异步,性能会大幅提升的 rocket;还有 tokio 社区刚刚发布没多久的后起之秀 axum。
比如你喜欢 Django 这样的大而全的 Web 框架,可以尝试 rocket 0.5 及以上版本。如果你特别在意 Web 性能,可以考虑 actix-web等。
2.3、数据库支持
从数据库的支持角度看,Rust 支持几乎所有主流的数据库,包括但不限于 MySQL、 Postgres、Redis、RocksDB、Cassandra、MongoDB、ScyllaDB、CouchDB 等等
2.4、模板引擎
从模板引擎的角度,Rust 有支持 jinja 语法的 askama,有类似 jinja2 的 tera,还有 处理 markdown的comrak。
2.5、Web 前端
从 Web 前端的角度,Rust 有纯前端的 yew 和 seed,以及更偏重全栈的 MoonZoon。其中,yew 更加成熟一些,熟悉 react/elm 的同学更容易用得起来。
2.6、Web 测试
从 Web 测试的角度看,Rust 有对标 puppeteer 的headless_chrome,以及对标 selenium 的thirtyfour 和 fantoccini。
2.7、云平台部署
从云平台部署的角度看,Rust 有支持 aws 的rusoto 和aws-sdk-rust、azure 的 azure-sdk-for-rust。目前 Google Cloud、阿里云、腾讯云还没有官方的 SDK 支持。
2.8、静态网站生成
在静态网站生成领域,Rust 有对标 hugo 的 zola 和对标 gitbook 的 mdbook。
3、客户端开发
这里的客户端,特指带 GUI 的客户端开发。在 areweguiyet.com 页面中,我们可以看到大量的 GUI 库。比较有前景的跨平台解决方案是 tauri、 druid、 iced 和 sixtyfps。
其中,tauri 是 electron 的替代品,如果你厌倦了 electron 庞大的身躯和贪婪的内存占 用,但又喜欢使用 Web 技术栈构建客户端 GUI,那么可以试试 tauri,它使用了系统自身 的 webview,再加上 Rust 本身极其克制的内存使用,性能和内存使用能甩 electron 好几 个身位。
如果你希望能够创建更加丰富,更加出众的 GUI,你可以使用 skia-safe 和 tiny- skia。前者是 Google 的 skia 图形引擎的 rust binding,后者是兼容 skia 的一个子集。skia 是目前在跨平台 GUI 领域炙手可热的 Flutter 的底层图形引擎,通过它你可以做任何 复杂的对图层的处理。
当然,你也可以用 Flutter 绘制 UI,用 Rust 构建逻辑层。Rust 可以输出 C FFI,dart 可 以生成 C FFI 的包装,供 Flutter 使用。
4、云原生开发
云原生一直是 Golang 的天下,如果你统计用到的 Kubernetes 生态中的 operator,几乎 清一色是使用 Golang 撰写的。
然而,Rust 在这个领域渐渐有冒头的趋势。这要感谢之前提到的 serde,以及处理 Kubernetes API 的 kube-rs 项目做出的巨大努力,还有 Rust 强大的宏编程能力,它使得我们跟 Kubernetes 打交道无比轻松。
除了 kube 这样的基础库,Rust 还有刚刚崭露头角的 krator 和 krustlet。krator 可 以帮助你更好地构建kubernetes operator。虽然 operator 并不太强调效率,但用更少的代码,完成更多的功能,还有更低的内存占用。krustlet 顾名思义,是用来替换 kubelet 的。krustlet 使用了 wasmtime 作为数据平台 (dataplane)的运行时,而非传统的 containerd。这也就意味着,你可以用更高效、更 精简的 WebAssembly 来处理原本只能使用 container 处理的工作。
云原生另一个主要的方向是 serverless。在这个领域,由于 amazon 开源了用 Rust 开发 的高性能 micro VM firecracker,使得 Rust 在 serverless/FAAS 方面处于领先地位。
5、WebAssembly
如果说 Web 开发,云原生是 Rust 擅长的领域,那么 WebAssembly 可以说是 Rust 主战场之一。
Rust 内置了 wasm32-unknown-unknown 作为编译目标,在编译的时候指明目标,就可以得到 wasm
你可以用 wasm-pack 和 wasm-bindgen,不但生成 wasm,同时还生成 ts/js 调用 wasm 的代码。wasmtime 可以让 WebAssembly 代码以沙箱的形式运行在服务器。
另外一个 WebAssembly 的运行时 wasmer,是 wasmtime 的主要竞争者。目前, WebAssembly 在服务器领域,尤其是 serverless / FAAS 领域,有着很大的发展空间。
6、嵌入式开发
如果你要用 Rust 做嵌入式开发,那么 embedded WG 不可不关注。
你也可以在 Awesome embedded rust 里找感兴趣的嵌入式开发工具。现在很多嵌入 式开发其实不是纯粹的嵌入式设备开发,所以云原生、边缘计算、WebAssembly 也在这 个领域有很多应用。比如被接纳为 CNCF sandbox 项目不久的 akri,它就是一个管理嵌 入式设备的云原生项目。
7、机器学习开发
机器学习 / 深度学习是 Rust 很有潜力,但目前生态还很匮乏的领域。
Rust 有 tensorflow 的绑定,也有 tch-rs 这个 libtorch(PyTorch)的绑定。除了这些著名的 ML 库的 Rust 绑定外,Rust 下还有对标 scikit-learn 的 linfa。
三、总结
以上介绍了Rust主要的几个方向上的生态。到目前为止,craters.io上有78k+的rust crate,足以涵盖工作中的方方面面的需求。
虽然Rust还有许多待完善的问题,但是Rust的生态还在蓬勃发展中。要知道Rust 的异步开发是 2019 年底才进入到稳定版本,在这不到两年的时间里,就出现了大量优秀的、基于异步开 发的库被创造出来。如果给 Rust 更长的时间,我们会看到更多的高性能优秀库会用 Rust 创造,或者用 Rust 改写。