├── .gitignore ├── Week7 ├── horizon.md ├── learn-rust-with-chatgpt.md ├── images │ └── chatgpt │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 7.png │ │ ├── 8.png │ │ ├── 9.png │ │ ├── 10.png │ │ ├── 11.png │ │ ├── 12.png │ │ ├── 13.png │ │ ├── 14.png │ │ ├── 15.png │ │ ├── 16.png │ │ ├── 17.png │ │ ├── 18.png │ │ ├── 19.png │ │ ├── 20.png │ │ ├── 21.png │ │ ├── 22.png │ │ └── 23.png └── learn-rust-with-chatgpt-zh.md ├── Week8 └── horizon.md ├── Week9 └── horizon.md ├── Week10 └── horizon.md ├── Week11 └── horizon.md ├── Week12 └── horizon.md ├── Week13 └── horizon.md ├── Week14 └── horizon.md ├── Week15 └── horizon.md ├── Week16 └── horizon.md ├── Week17 └── horizon.md ├── Week18 └── horizon.md ├── Week19 └── horizon.md ├── Week20 └── horizon.md ├── Week21 └── horizon.md ├── Week22 └── horizon.md ├── Week23 └── horizon.md ├── Week24 └── horizon.md ├── Week25 └── horizon.md ├── Week26 └── horizon.md ├── Week27 └── horizon.md ├── Week28 └── horizon.md ├── Week29 └── horizon.md ├── Week30 └── horizon.md ├── Week31 └── horizon.md ├── Week32 └── horizon.md ├── Week33 └── horizon.md ├── Week34 └── horizon.md ├── Week35 └── horizon.md ├── Week36 └── horizon.md ├── Week37 └── horizon.md ├── Week38 └── horizon.md ├── Week39 └── horizon.md ├── Week40 └── horizon.md ├── Week41 └── horizon.md ├── Week42 └── horizon.md ├── Week43 └── horizon.md ├── Week44 └── horizon.md ├── Week45 └── horizon.md ├── Week46 └── horizon.md ├── Week47 └── horizon.md ├── Week48 └── horizon.md ├── Week49 └── horizon.md ├── Week50 └── horizon.md ├── Week51 └── horizon.md ├── Week52 └── horizon.md ├── Week1 ├── .DS_Store ├── images │ ├── .DS_Store │ └── compling.png ├── study-resources.md └── horizon.md ├── Week4 ├── images │ ├── rust-girl.png │ └── rust-girl-errors.png ├── study-resources.md ├── rust-1-67.md └── horizon.md ├── README.md ├── Week5 ├── study-resources.md └── horizon.md ├── Week6 ├── study-resources.md └── horizon.md ├── Week3 ├── study-resources.md └── horizon.md └── Week2 ├── study-resource.md └── horizon.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /Week7/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 7 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week8/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 8 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week9/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 9 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week10/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 10 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week11/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 11 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week12/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 12 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week13/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 13 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week14/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 14 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week15/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 15 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week16/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 16 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week17/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 17 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week18/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 18 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week19/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 19 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week20/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 20 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week21/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 21 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week22/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 22 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week23/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 23 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week24/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 24 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week25/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 25 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week26/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 26 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week27/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 27 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week28/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 28 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week29/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 29 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week30/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 30 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week31/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 31 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week32/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 32 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week33/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 33 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week34/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 34 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week35/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 35 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week36/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 36 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week37/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 37 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week38/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 38 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week39/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 39 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week40/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 40 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week41/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 41 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week42/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 42 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week43/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 43 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week44/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 44 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week45/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 45 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week46/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 46 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week47/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 47 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week48/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 48 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week49/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 49 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week50/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 50 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week51/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 51 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week52/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 52 2 | --- 3 | 4 | -------------------------------------------------------------------------------- /Week7/learn-rust-with-chatgpt.md: -------------------------------------------------------------------------------- 1 | # Learn Rust With ChatGPT 2 | 3 | 4 | -------------------------------------------------------------------------------- /Week1/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week1/.DS_Store -------------------------------------------------------------------------------- /Week1/images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week1/images/.DS_Store -------------------------------------------------------------------------------- /Week1/images/compling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week1/images/compling.png -------------------------------------------------------------------------------- /Week4/images/rust-girl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week4/images/rust-girl.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/1.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/2.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/3.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/4.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/5.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/6.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/7.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/8.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/9.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/10.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/11.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/12.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/13.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/14.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/15.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/16.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/17.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/18.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/19.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/20.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/21.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/22.png -------------------------------------------------------------------------------- /Week7/images/chatgpt/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week7/images/chatgpt/23.png -------------------------------------------------------------------------------- /Week4/images/rust-girl-errors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustMagazine/rust-horizon-2023/HEAD/Week4/images/rust-girl-errors.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rust Horizon 2023 / Rust 视界 2023 2 | 3 | 观察 Rust 2023 生态发展,欢迎大家补充贡献! 4 | 5 | > 说明:周刊,是指每周发布,并不限制发布内容必须是当周的动态。 6 | 7 | ## 列表 8 | 9 | - [Week 1](./Week1/horizon.md) 10 | - [Week 2](./Week2/horizon.md) 11 | - [Week 3](./Week3/horizon.md) 12 | - [Week 4](./Week4/horizon.md) 13 | - [Week 5](./Week5/horizon.md) 14 | - [Week 6](./Week6/horizon.md) -------------------------------------------------------------------------------- /Week5/study-resources.md: -------------------------------------------------------------------------------- 1 | ## 学习资源 2 | 3 | - [future 的大小](https://swatinem.de/blog/future-size/) 4 | - [Bevy 实现微信跳一跳游戏](https://github.com/NightsWatchGames/jump-jump) 5 | - [WIP:关于解释 Rust 生命周期的一本书](https://danielhenrymantilla.github.io/lifetimes.rs/variance-rules.html) 6 | - [cargo-dist issues#74 关于交叉编译的一些讨论与资源](https://github.com/axodotdev/cargo-dist/issues/74) 7 | - [Rust 面向对象特性研究系列文章](https://www.thecodedmessage.com/posts/oop-1-encapsulation/) 8 | - [Rust 声明宏介绍](https://www.priver.dev/blog/rust/macros-in-rust/) 9 | - [derive-adhoc:强大的基于模式的 Rust 派生宏](https://diziet.dreamwidth.org/14345.html) -------------------------------------------------------------------------------- /Week1/study-resources.md: -------------------------------------------------------------------------------- 1 | # 学习资源记录 2 | 3 | 4 | ## RustLab 2022: 5 | 6 | - 困难问题的人体工程学 API: 7 | - [YB](https://www.youtube.com/watch?v=Phk0C-kLlho) 8 | - [slids](https://docs.google.com/presentation/d/1P8Su5mZSYkfZ1A9mPAaKag-vtXmVD8nUBD7Ym-pfwJM/edit#slide=id.gff4f80ffe4_0_0) 9 | 10 | - 使用Tokio 实现 Actors: [YB](https://www.youtube.com/watch?v=fTXuGRP1ee4) 11 | 12 | ## Web 开发 13 | 14 | - [使用 actix-web 和模板引擎Tera 创建站点框架](https://webant.online/tutorials/actix-web-tera-skeleton-website/) 15 | 16 | ## Rust vs C++ 常见 Bug 对比 17 | 18 | ReadMore: [https://geo-ant.github.io/blog/2022/common-cpp-errors-vs-rust/](https://geo-ant.github.io/blog/2022/common-cpp-errors-vs-rust/) 19 | 20 | ## 《Rust Atomics and Locks》免费在线阅读 21 | 22 | [https://marabos.nl/atomics/](https://marabos.nl/atomics/) 23 | 24 | ## Haskell 程序员用 Rust 抽象 25 | 26 | [https://www.jernesto.com/articles/who_needs_haskell.html](https://www.jernesto.com/articles/who_needs_haskell.html) 27 | 28 | ## egui写的票务管理工具 29 | 30 | [https://github.com/TheBiochemic/tickets-rs](https://github.com/TheBiochemic/tickets-rs) 31 | 32 | ## 基于 wasm 的unix终端 33 | 34 | [https://github.com/Property404/its-a-unix-system](https://github.com/Property404/its-a-unix-system) -------------------------------------------------------------------------------- /Week4/study-resources.md: -------------------------------------------------------------------------------- 1 | ## 学习资源 2 | 3 | - [Future 的大小](https://swatinem.de/blog/future-size/) 4 | - [DGS: 3D 围棋 Rust 实现,支持 wasm 和 VR,前端基于 3D JS/TS 库 BabylonJS 和 SolidJS 实现](https://github.com/Dominux/DGS) 5 | - [使用 Rust 开发简单数据库系列文章(连载中)](https://johns.codes/blog/build-a-db/part02) 6 | - [ Rust 语法为什么“丑陋”?这篇文章教你如何去除 Rust 语法噪音而阅读 Rust 代码](https://matklad.github.io/2023/01/26/rusts-ugly-syntax.html) 7 | - [系列文章探索在 HAL 级别使用嵌入式 Rust 的 STM32F401RE 微控制器之GPIO 中断](https://apollolabsblog.hashnode.dev/stm32f4-embedded-rust-at-the-hal-gpio-interrupts) 8 | - [Rust 中如何处理整数溢出](https://bmoxb.io/2023/01/28/integer-overflow-in-rust.html) 9 | - [边做边学: Rust构建 HTTP API 服务](https://blog.frankel.ch/http-api-rust/) 10 | - [使用 Rust 开发原生 iOS 应用](https://itnext.io/native-ios-game-development-w-rust-a1134887c35f) 11 | - [将递归重写为迭代](https://azdavis.net/posts/unrecur/) 12 | - [能力安全(capability-safety)系列文章](https://blog.yoshuawuyts.com/capabilities-1/) 13 | - [临时值、借用和生命周期](https://blog.vashishtha.in/temporary-lifetimes/) 14 | - [实现工厂模式 - 处理借用检查的限制](https://kazlauskas.me/entries/due-to-borrowck-limitations) 15 | - [Rust FFI 和 cbindgen:在 C 中集成嵌入式 Rust 代码](https://apollolabsblog.hashnode.dev/rust-ffi-and-cbindgen-integrating-embedded-rust-code-in-c) 16 | - [14 个适用于 Linux 终端的 Rust 工具](https://itsfoss.com/rust-cli-tools/) 17 | - [特定领域的错误宏](https://blog.yoshuawuyts.com/ensure-macros/) 18 | - [使用 Rust 和 nannou 模拟遗传算法](https://github.com/sujay-ee/rust-genetic-rockets) 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Week6/study-resources.md: -------------------------------------------------------------------------------- 1 | ## 学习资源 2 | 3 | - [Rustproofing Linux: 研究如何将C驱动迁移到Rust上来的最佳实践系列文章](https://research.nccgroup.com/2023/02/06/rustproofing-linux-part-1-4-leaking-addresses/) 4 | - [减少 AccessKit(跨平台和编程语言的 UI 可访问性基础设施,Rust 实现) 的内存使用报告](https://accesskit.dev/dramatically-reducing-accesskits-memory-usage/),[egui 的 PR](https://github.com/emilk/egui/commit/853d49272471cc930532798840f3101ae4bca81f) 做了这项优化工作。 5 | - [探讨如何使用 Rust 限制 Windows 上 DirectX 11 游戏的 FPS](https://zazama.de/blog/creating-an-fps-limiter-in-rust-by-hooking-directx) 6 | - [Video: 使用 nom-supreme 编写更好的解析器](https://www.youtube.com/watch?v=Ph7xHhBfH0w),[nom-supreme](https://github.com/Lucretiel/nom-supreme) 是一个扩展了 Nom 的库,Nom 是一个用于 Rust 的解析器组合器库。 7 | - [使用 Rust 和 PEG 编写解析器](https://blog.logrocket.com/building-rust-parser-pest-peg/) 8 | - [如果使用 Rustler 在 Elixir 项目中使用 Rust crate ](https://mainmatter.com/blog/2023/02/01/using-rust-crates-in-elixir/) 9 | - [系列文章:探索 Rust 编写 Vulkan 驱动程序](https://www.collabora.com/news-and-blog/blog/2023/02/02/exploring-rust-for-vulkan-drivers-part-1/) 10 | - [PAC 上的 STM32F4 嵌入式 Rust:svd2rust](https://apollolabsblog.hashnode.dev/stm32f4-embedded-rust-at-the-pac-svd2rust) 11 | - [Tauri vs Iced vs egui:Rust GUI 框架性能比较(包括启动时间、输入滞后、调整大小测试)](https://lukaskalbertodt.github.io/2023/02/03/tauri-iced-egui-performance-comparison.html) 12 | - [从 Erlang 到 Lunatic: 一位 Eralng 程序员的 Rust 旅途](https://mattpo.pe/posts/from-erlang-to-lunatic/)。 [Lunatic](https://github.com/lunatic-solutions/lunatic) 是一种 Erlang 风格的 wasm 运行时,并且提供了一个现代化 Web 框架 [submillisecond](https://github.com/lunatic-solutions/submillisecond)。 -------------------------------------------------------------------------------- /Week3/study-resources.md: -------------------------------------------------------------------------------- 1 | ## 学习资源 2 | 3 | - [Lifetime Kata 生命周期练习题](https://tfpk.github.io/lifetimekata/index.html) ,[另一个 lifetime 练习](https://github.com/mtomassoli/lifetimes) 4 | - [如何避免 Rust 中的边界检查](https://shnatsel.medium.com/how-to-avoid-bounds-checks-in-rust-without-unsafe-f65e618b4c1e) ,[reddit 相关讨论](https://www.reddit.com/r/rust/comments/10edmjf/how_to_avoid_bounds_checks_in_rust_without_unsafe/) 5 | - [rlox: 《Crafting Interpreters》 的 Rust 实现](https://github.com/mogendi/rlox) 6 | - [Hindley-Milner 类型推断算法的玩具实现](https://github.com/veera-sivarajan/type-inferencer),[Reddit 相关讨论](https://www.reddit.com/r/rust/comments/10fxmcw/show_rrust_wrote_a_toy_type_inferencer_by/) 7 | - [Rust 运算符重载的六件有趣的事情](https://wishawa.github.io/posts/fun-rust-operators/) 8 | - [来自 Rails 开发者的 Rust web 实践(基于 Axum)](https://thoughtbot.com/blog/axum-from-a-rails-perspective) 9 | - [我希望我早点学过的 Rust 概念](https://rauljordan.com/rust-concepts-i-wish-i-learned-earlier/),更多 [reddit 讨论](https://www.reddit.com/r/rust/comments/10eu2aw/rust_concepts_i_wish_i_learned_earlier/) 10 | - [Rust 中的类型擦除 trait 参数](https://fredrik.space/posts/rust-erased-trait-parameters/) 11 | - [AI 辅助学习:使用 ChatGPT、Copilot 和 Advent of Code 学习 Rust](https://simonwillison.net/2022/Dec/5/rust-chatgpt-copilot/) 12 | - [构建out-of-tree Rust 内核模块(基于 Linux 6.1 内核)](https://blog.rnstlr.ch/building-an-out-of-tree-rust-kernel-module.html) 13 | - [关于 interoperable_abi 提案的讨论:我们需要的是类型系统](https://blaz.is/blog/post/we-dont-need-a-stable-abi/) 14 | - [Rust 国外招聘职位统计](https://filtra.io/rust-dec-22) 15 | - [使用 Rust 写 Web 爬虫教程](https://www.scrapingdog.com/blog/web-scraping-with-rust/) 16 | - [Rust FFI 和 bindgen:在 Rust 中集成嵌入式 C 代码](https://apollolabsblog.hashnode.dev/rust-ffi-and-bindgen-integrating-embedded-c-code-in-rust) 17 | - [使用 Rust 在 ESP32 上显示图像](https://lilymara.xyz/posts/images-esp32/) 18 | - [使用 Rust 寻找好的 MD5-尝试 Rust 的 SIMD 和内联汇编的旅程](https://blog.youmu.moe/posts/finding-nice-md5s-using-rust/) 19 | - [使用 OpenAI 和 Rust 搜索歌曲](https://gigapotential.dev/blog/song-search-in-rust-using-openai/) 20 | - [光线追踪挑战](https://www.superperfundo.tech/articles/ray-tracer-part1) -------------------------------------------------------------------------------- /Week2/study-resource.md: -------------------------------------------------------------------------------- 1 | ## 学习资源 2 | 3 | ### 那些Rust交叉编译的坑 4 | 5 | [https://felix-knorr.net/posts/2023-01-11-cross-compiling-rust.html](https://felix-knorr.net/posts/2023-01-11-cross-compiling-rust.html) 6 | 7 | ### 101-rs Rust 教程(WIP) 8 | 9 | [https://101-rs.tweede.golf/](https://101-rs.tweede.golf/) 10 | 11 | ### 教程:将C++代码移植到Rust之体验 12 | 13 | AdventOfCode 比赛代码 14 | 15 | [https://fasterthanli.me/series/advent-of-code-2022/part-18](https://fasterthanli.me/series/advent-of-code-2022/part-18) 16 | 17 | ### mdbook pdf 生成 18 | 19 | [https://github.com/RosiePuddles/mdbook-compress/](https://github.com/RosiePuddles/mdbook-compress/) 20 | 21 | ### 面向 Java 开发者的 Rust 简介 22 | 23 | [https://wcgw.dev/posts/2023/rusty-java-intro/](https://wcgw.dev/posts/2023/rusty-java-intro/) 24 | 25 | ### 探索 Android 上 Rust 对 SIMD 支持的系列文章 26 | 27 | [https://gendignoux.com/blog/2023/01/05/rust-arm-simd-android.html](https://gendignoux.com/blog/2023/01/05/rust-arm-simd-android.html) 28 | 29 | ### Running Zola on WebAssembly 30 | 31 | [https://dstaley.com/posts/running-zola-on-wasm/](https://dstaley.com/posts/running-zola-on-wasm/) 32 | 33 | ### 嵌入式 Rust 异步:在 Embassy 中的任务之间共享数据 34 | 35 | [https://apollolabsblog.hashnode.dev/sharing-data-among-tasks-in-rust-embassy-synchronization-primitives](https://apollolabsblog.hashnode.dev/sharing-data-among-tasks-in-rust-embassy-synchronization-primitives) 36 | 37 | ### 使用 Drone 交叉编译 Rust 38 | 39 | [https://jacobkiers.net/post/rust-cross-compilation-on-drone/](https://jacobkiers.net/post/rust-cross-compilation-on-drone/) 40 | 41 | ### 使用 decorate-sort-undecorate 加速排序 42 | 43 | [https://morestina.net/blog/1916/faster-sorting-with-decorate-sort-undecorate](https://morestina.net/blog/1916/faster-sorting-with-decorate-sort-undecorate) 44 | 45 | ### Rust 实现 加权图 和 Dijkstra 算法 46 | 47 | [https://galiullin.online/articles/pWK2sAKzCf](https://galiullin.online/articles/pWK2sAKzCf) 48 | 49 | ### Folding arguments into the macro 50 | 51 | [https://nnmm.github.io/rust/2023/01/11/folding-arguments-into-the-macro.html](https://nnmm.github.io/rust/2023/01/11/folding-arguments-into-the-macro.html) 52 | 53 | ### Rust 函数式编程简介 54 | 55 | [https://www.youtube.com/watch?v=2rv-V2upU1U](https://www.youtube.com/watch?v=2rv-V2upU1U) -------------------------------------------------------------------------------- /Week4/rust-1-67.md: -------------------------------------------------------------------------------- 1 | # Rust 1.67 稳定版语言特性一瞥 2 | 3 | [Rust 1.67 稳定版发布了](https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1670-2023-01-26) 。 4 | 5 | 以下摘录三个值得关注的语言特性。 6 | 7 | ## 让 `Sized` trait 可共归纳(Coinductive) 8 | 9 | 在 1.67 之前,下面代码编译不通过: 10 | 11 | ```rust 12 | struct Node>(C::Assoc); 13 | 14 | trait Trait { 15 | type Assoc; 16 | } 17 | 18 | impl Trait for Vec<()> { 19 | type Assoc = Vec; 20 | } 21 | 22 | fn main() { 23 | let _ = Node::>(Vec::new()); 24 | // as Trait>>> 25 | // Node( as Trait>>>::Assoc ) 26 | } 27 | ``` 28 | 29 | 报错如下: 30 | 31 | ```rust 32 | error[E0275]: overflow evaluating the requirement `Node>: Sized` 33 | --> src/main.rs:12:13 34 | | 35 | 12 | let _ = Node::>(Vec::new()); 36 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 37 | | 38 | note: required because of the requirements on the impl of `Trait>>` for `Vec<()>` 39 | --> src/main.rs:7:9 40 | | 41 | 7 | impl Trait for Vec<()> { 42 | | ^^^^^^^^ ^^^^^^^ 43 | 44 | For more information about this error, try `rustc --explain E0275`. 45 | ``` 46 | 47 | 这个[错误码`E0275`](https://doc.rust-lang.org/error_codes/E0275.html)表示在在解析某些类型限定时存在无限递归。具体到上面代码,是计算`Node>: Sized` 的 `Sized` 限定时产生了无限递归。 48 | 49 | 上面代码 `Sized` 的正常推理逻辑是: 50 | 51 | 1. 如果 ` as Trait>>::Assoc` 是 `Sized`,则要求 `Node>` 是 `Sized` 。 52 | 2. 这就要求 `Vec>` 是 `Sized`,因此再次需要 `Node` 是 `Sized`。 53 | 54 | 这就造成了递归。在 1.67 stable 之后,[`Sized` 现在是共归纳(coinductive)](https://github.com/rust-lang/rust/pull/100386/),就不会再次报错。 55 | 56 | > 说明:共归纳(coinductive)是类型理论里的术语,用于处理递归类型。 57 | 58 | ### `#[must_use]` 现在支持 `async fn` 59 | 60 | `#[must_use]` 作用于 `async fn` 则会影响到 `Future::Output`,意味着下面异步函数: 61 | 62 | ```rust 63 | #[must_use] 64 | async fn bar() -> u32 { 0 } 65 | 66 | async fn caller() { 67 | bar().await; 68 | } 69 | ``` 70 | 71 | 在未使用 `Future::output` 时会输出下面警告: 72 | 73 | ```rust 74 | warning: unused output of future returned by `bar` that must be used 75 | --> src/lib.rs:5:5 76 | | 77 | 5 | bar().await; 78 | | ^^^^^^^^^^^ 79 | | 80 | = note: `#[warn(unused_must_use)]` on by default 81 | ``` 82 | 83 | ### `std::sync::mpsc` 合并了 `crossbeam_channel` 的 mpsc 84 | 85 | `std::sync::mpsc`现在被[切换为基于`crossbeam-channel`](https://github.com/rust-lang/rust/pull/93563/)。这次合并是为了解决 `std::sync::mpsc` 多年未解决的 Bug,以及提高了实现的性能和可维护性,并不包含任何 API 更改。 86 | 87 | 所以,如果你需要使用 `mpmc` channel,则还需要使用 `crossbeam-channel` 第三方库。使用 `mpsc` 的话,则用标准库的就可以了。 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /Week1/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 1 2 | --- 3 | 2023/01/07 4 | 5 | ## 社区热点 6 | 7 | ### Rust 官方正在讨论 为 Rust 提供 interoperable_abi features gate 8 | 9 | [interoperable_abi](https://github.com/rust-lang/rust/pull/105586) 意味着提供一个新的 Rust ABI extern "interop" 和 repr(interop) ,用于实现有安全数据 类型的高级编程语言之间的互操作性。 10 | 11 | ![interoperable_abi](https://user-images.githubusercontent.com/783247/207410320-695a8f34-e721-45cd-84bf-9020d0945bc9.png) 12 | 13 | 动机摘要: 14 | 15 | 目前 Rust ABI 并不稳定,多语言交互只能通过 C-ABI 来进行。但是这限制了在 ABI 之间使用更高级的安全类型。可互操作的 ABI 将定义一种标准方法来跨高级语言进行调用,传递高级数据类型,而不需要将其降级为 C-ABI。该 ABI 将与任何提供 16 | C 兼容 FFI 的语言(包括 C本身),并且语言还可以为可互操作的 ABI 添加特定的更高级别的支持。可互操作的 ABI 旨在成为 17 | 静态和动态形式的编译库(包括系统库)的合理默认值。 18 | 19 | 可互操作的 ABI 将是 C ABI 的严格超集。 20 | 21 | 可互操作 ABI 不支持的内容摘要: 22 | 23 | - 可互操作的 ABI 并不旨在支持整个Rust 标准库. 24 | - 可互操作的 ABI 不会旨在支持复杂的生命周期处理 25 | - 可互操作的 ABI(至少在第一个版本中)不会以源代码或编译形式提供接口描述语言(IDL) 26 | - 可互操作的 ABI 的目的不是在不同语言的表示之间提供“翻译” 27 | - 可互操作的 ABI 不能支持任意的编译时泛型函数 28 | 29 | 30 | ### GCC-rs 项目在 2022 年取得了很大进展 31 | 32 | gccrs是一个旨在为 GNU Compiler Collection 带来对 Rust编程语言的支持的项目。其目标是从头开始为 Rust 编程语言编写一个新的编译器前端,将该前端集成到 GCC 中,使其作为一种语言与 C、C++、Ada、D、Go 一起使用。 33 | 34 | 该项目最初于 2014 年启动。当时,Rust 尚未实现稳定版本(Rust 1.0 于 2015 年 5 月发布),对于单个开发人员来说很难跟上高强度的变化。2019年又开始努力,此后一直在稳步进行。 35 | 36 | 2020 年,菲利普·赫伦 ( Philip Herron )开始获得资金支持,随后他得以开始全职从事该项目。此赞助来自 Open Source Security公司。Philip 受雇于 Embecosm 并从他们的管理中受益,并得到 GCC 指导委员会的支持。2022 年,在将近一年半的单飞之后,Philip 加入了另一位由 Open Source Security 公司资助的全职工程师 Arthur Cohen ,也受雇于 Embecosm。现在有两名工程师每周为该项目投入 40 小时。 37 | 38 | 2022 年发生的最引人注目的事件是将 gccrs 合并到 GCC,gccrs 将在 2023 年 4 月发布的 GCC 13.1 版本中可用。 39 | 40 | [更多内容参考 gccrs 2022 年报](https://rust-gcc.github.io/reporting/2022-year-report.html) 41 | 42 | > P.S 与 gccrs 对应的是另一个项目 `rustc_codegen_gcc`。它是作为 Rust 编译器 GCC 后端,目前也正在积极开发中,感兴趣可以关注[rustc_codegen_gcc:进度报告#19](https://blog.antoyo.xyz/rustc_codegen_gcc-progress-report-19)。 43 | 44 | 45 | ### 用 Rust 和 C++ 代码编译时间同样糟糕吗? 46 | 47 | [原文](https://quick-lint-js.com/blog/cpp-vs-rust-build-times/)作者写道: 48 | 49 | > C++ 因其缓慢的构建时间而臭名昭著。“我的代码正在编译”是编程世界中的一个梗,而 C++ 让这个笑话流传开来。 50 | 51 | ![compling](./images/compling.png) 52 | 53 | > 像 Google Chromium 这样的项目 在全新硬件上构建需要一个小时,在旧硬件上构建需要 6 小时。即使有数千美元的云计算能力,Chromium 构建时间仍然在六分钟左右。这是我完全不能接受的。人怎么可以每天这样工作? 54 | 55 | 作者也听说,Rust 也面临相同的问题,但他有实证精神,亲自动手证明一下 Rust 是不是和 Cpp 一样很慢。 56 | 57 | 这是他的计划: 58 | 59 | - 查找开源 C++ 项目。 60 | - 从项目中提取一部分为迷你项目中。 61 | - 将 C++ 迷你项目的代码逐行重写为 Rust。 62 | - 优化 C++ 项目和 Rust 项目的构建工具链。 63 | - 比较两个项目之间的编译+测试时间。 64 | 65 | 经过这样的测试,作者得出最终结论: 66 | 67 | - 编译时间是 Rust 的问题吗?是的。有一些提示和技巧可以加快构建速度,但作者没有找到神奇的数量级改进,否则作者将很高兴使用 Rust 进行开发。 68 | - Rust 的构建时间和 C++ 一样糟糕吗?是的。对于更大的项目,Rust 的开发编译时间比 C++ 更短,至少作者的代码风格是这样。 69 | - 对于完整构建,C++ 构建花费的时间与 Rust 相比,大致相同(17k SLOC)或花费更少的时间(100k+ SLOC),而不是更长。 70 | - 对于增量构建,与 C++ 相比,Rust 构建有时更短,有时更长(17k SLOC)或更长(100k+ SLOC),但并不总是更长。 71 | - 很欣赏 Rust 的工具链(尤其是 Cargo、rustup 和 miri)。 72 | 73 | ## 应用实践 74 | 75 | ### Gama 发射的太阳帆宇宙飞船中使用了 Rust 76 | 77 | [Gama](https://www.gamaspace.com/) 将发射太阳帆宇宙飞船🛰️,并且是公开将 Rust 送入太空的公司之一。提供软件服务的应该是这家公司:[Tweedegolf](https://tweedegolf.nl/en) ,该公司也是 Rust 基金会银牌会员。他们的[开源仓库](https://github.com/tweedegolf)里有一个 Rust 实现的 PTP (精确时间协议) 库,这个PTP一般用在卫星的时间源,比NTP更精确。但这个是 PoC 实现,不知道这次发射的飞船上有没有用。从另外的项目 嵌入式开发板 pcf85063a (一般用于计时闹钟)rust 驱动来看,这次上天的 Rust 程序很可能和精确计时相关。 78 | 79 | [Gama 太阳帆的卫星于 2023 年 1 月 3 日由 SpaceX 猎鹰 9 号成功送入轨道](https://www.sail-world.com/news/257330/Gama-launches-its-Gama-Alpha-solar-sail-mission)。 80 | 81 | 82 | ## 生态看点 83 | 84 | ### svix-webhooks: 企业级 Webhooks 服务 85 | 86 | [svix-webhooks](https://github.com/svix/svix-webhooks) 是基于 Rust 实现的企业级 Webhooks 服务器。Svix 使开发人员可以轻松发送 webhook。开发人员进行一次 API 调用,Svix 负责可交付性、重试、安全性等。 87 | 88 | ### turmoil:开发和测试分布式系统的框架 89 | 90 | [Tokio 发布了](https://tokio.rs/blog/2023-01-03-announcing-turmoil)用于开发和测试分布式系统的框架 [turmoil](https://github.com/tokio-rs/turmoil) 的初始版本。 91 | 92 | 测试分布式系统很难。不确定性无处不在(网络、时间、线程等),使得难以实现可重现的结果。由于部署,开发周期很长。所有这些因素都会减慢开发速度,并且难以确保系统的正确性。turmoil力求通过模拟主机、时间和网络来解决这些问题。这允许整个分布式系统在单个线程的单个进程中运行,从而实现确定性执行。 93 | 94 | ### cargo-sandbox 发布 95 | 96 | [cargo-sandbox](https://github.com/insanitybit/cargo-sandbox) 打算成为 cargo 的一个近乎直接的替代品。关键的区别在于,cargo-sandbox 在 docker 容器中运行相关命令,目的是将潜在的恶意代码与主机环境的隔离开来(关于威胁模型的更多细节,见README)。 其目标是尽可能地接近 "100%"的兼容原版 cargo,并获得最顺畅的体验。 97 | 98 | ### Rust 中的深度学习:Burn 0.4.0 发布以及 2023 年的规划 99 | 100 | Rust 深度学习框架[Burn](https://github.com/burn-rs/burn) 0.4 完成了后端重构,除此之外,还实现了很多新的功能,如ADAM优化器、转化器模块等。下一个重点将是增加视觉相关的模块,如卷积和池化层。 101 | 102 | 103 | ### shura-一个安全的2D 游戏引擎,易于创建易于管理的游戏 104 | 105 | [shura](https://github.com/AndriBaal/shura) 是rust编写的一个安全,快速并且跨平台的游戏框架。shura使用一个2D组件系统、场景管理和group系统帮你管理一个大型游戏。 106 | 107 | shura主要的目标是,你的游戏逻辑可以分别放在不同的组件、group和场景中。 108 | 109 | 110 | ### rumqtt: 构建 mqtt 的 Rust 生态 111 | 112 | [rumqtt](https://github.com/bytebeamio/rumqtt) 是一组用 rust-lang 编写的开源库,用于实现 MQTT 标准,同时力求简单、健壮和高性能。 113 | 114 | rumqtt 是 Bytebeam 物联网咨询公司开源的 MQTT 代理。rumqtt 目前版本已经发布到了 R19 版,并未按语义化版本来发布。 115 | 116 | 目前发布了 R19 新版本: 117 | 118 | - 新的版本提升了性能和可靠性(可以支持 多达 10,000 多个 MQTT 客户端,使用 [mqttwrk](https://github.com/bytebeamio/mqttwrk) 进行基准测试) 119 | - 添加了一个用于测试 rumqttd 的公共服务器 120 | - 添加了 Prometheus 集成和其他优化更改 121 | - 加了对存储支持的持久性的实验性支持,以确保消息的零数据丢失 122 | 123 | rumqtt 将在 2023 年初推出对 MQTT v5 的支持。 124 | 125 | > P.S 另外一个纯 Rust MQTT v5 客户端实现 [mqrstt](https://github.com/GunnarMorrigan/mqrstt) -------------------------------------------------------------------------------- /Week6/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 6 | 黑莓公司宣布:汽车行业需要 Rust 2 | --- 3 | 4 | 5 | ## 社区热点 6 | 7 | ### 谁“拥有” Rust 语言? 8 | 9 | [Reddit 有人发帖发问:谁“拥有” Rust 语言?](https://www.reddit.com/r/rust/comments/10z6qnu/who_owns_rust/) 。因为他最近听说 Google 打算在 Golang pipline 中内置 telemetry, 这是他不可接受的,他想寻找一门完全开源不受某个公司控制的编程语言。 10 | 11 | Rust 语言的创造者 Graydon 亲自回复如下。 12 | 13 | 目前和 Rust 语言相关有两个组织: 14 | 15 | - Rust基金会,这是一家非营利性综合(特拉华州)公司,拥有章程、员工和正常的合法存在。它拥有商标和域名,在需要时充当法律和行政联络点,并且我认为对基础设施(crates.io、CI 等)的运营和资金负责。该基金会的成员几乎都是捐钱(有时捐人)以推进其使命的企业赞助商。这里涉及相当广泛的公司:微软、谷歌、亚马逊、Meta、华为等。 16 | - Rust项目是一个非法律实体的人员集合(一些受雇于公司,一些是志愿者),他们自组织成团队(主要选择他们自己未来的成员)通过互联网协作,每个人都有自己的职责范围。他们有自己的流程和治理系统(在上一代流程遇到一些问题后,他们目前正在进行相当大的改革)。该项目实际上负责所有技术决策,包括语言的内容、工具和流程的工作方式、文档中的内容、更改的功能以及更改时间等。将做出诸如“我们应该将telemetry放入编译器”之类的决定,而不是基础。 17 | 18 | Rust项目不接受基金会的指导,基金会也不接受项目的指导。它们并行存在,并且是大部分独立的实体,具有大部分独立的责任领域,尽管有几个人在两者中都扮演着角色。到目前为止,据我所知,他们之间没有发生任何严重的冲突,我也不太清楚如果有会发生什么。但基金会的任务是支持该项目,所以如果他们发现自己发生冲突,情况会有些奇怪。 19 | 20 | ### 有人认为 stc 这个项目不道德,对于 typescript 社区是毒药,你怎么看? 21 | 22 | stc 是用 Rust 编写的 TypeScript 类型检查器 ,目标是性能更好,使用 Rust 实现。 该 [stc 的 issue](https://github.com/dudykr/stc/issues/647) 的作者认为,stc如果做好了,会因此而获得控制 TS 规范的能力。并且让stc作者转而去实现另外一个 类型化js的实现。 23 | 24 | stc作者回复:“typescript 本身没有规范,所以我无法控制它。如果 TypeScript 有规范,情况会有所不同,但事实并非如此,如果有,tsc它本身就是规范。” 25 | 26 | 我的观点: 人们肯定期望更好的工具,并且它会带走流量,这是自然规律。 这个 issues 作者太奇葩了,人们不能阻止竞争对手的发展来迎合自己的用户,这才是不道德的。 27 | 28 | ### Reddit 讨论:`#[must_use]`没有成为函数的默认值违背了“Rust 具有最安全的默认值”的原则 29 | 30 | [reddit 一篇题为 《`#[must_use]`没有成为函数的默认值违背了“Rust 具有最安全的默认值”的原则》](https://www.reddit.com/r/rust/comments/10wz3am/must_use_not_being_the_default_on_functions_goes/)的文章,引起了社区的讨论。 31 | 32 | 作者认为,Rust 犯了与 C++17 的`[[nodiscard]]`属性相同的错误,他认为: 33 | 34 | 1. 大多数返回值的函数,无论它们是否有副作用,都应该以某种方式使用它们的返回值 35 | 2. 一些返回值和有副作用的函数可能在不检查返回值的情况下被正确使用 36 | 3. 当函数的返回值未被使用时,编译器发出警告是有益的,因为在大多数情况下这是一个错误 37 | 4. 因此,作为一个负责任的程序员,除了我有意决定丢弃返回值不是错误的地方外,我应该把它放在`#[must_use]`下 38 | 39 | reddit 下面一些回复摘要: 40 | 41 | - “`F#` 中的这是默认值。它之所以有效,是因为 `F#` 主要是一种函数式语言,因此您通常创建纯函数,结果应该用于进一步的计算。然而,在 `F#` 中编写命令式代码时,您经常需要使用`ignore`。考虑到纯函数很少而且介于两者之间,这将成为 Rust 的一大麻烦”。 42 | - “`#[must_use]`与安全无关,它是为了明确某些返回值(少数)值得处理。如果它成为默认值,它就失去了意义。更糟糕的是,如果成本高到人们禁用 lint,带来的结果也许更糟糕。” 43 | - “这其实是对 Rust 的普遍误解!Rust 并不努力成为“默认情况下完全安全”,Rust 并没有试图实现“完美的安全性”,但它试图让您的程序在一个由人类编写程序的世界中尽可能安全可靠。” 44 | 45 | 更多的讨论内容可以参考原帖。 46 | 47 | 48 | ## 应用实践 49 | 50 | ### 黑莓公司宣布:汽车行业需要 Rust 51 | 52 | [blackberry 官方平台发文宣称](https://blogs.blackberry.com/en/2023/02/this-is-the-kind-of-rust-the-automotive-industry-needs),软件定义汽车(SDV) 领域需要 Rust 语言带来更多安全优势。 53 | 54 | > BlackBerry和 [Elektrobit](https://www.elektrobit.com/) 最近汇集了他们的专业知识,共同支持 Rust,使开发人员能够构建安全、可靠和高效的汽车软件。Elektrobit 和BlackBerry QNX作为合作伙伴有着悠久的历史,并且拥有强大的、经过生产验证的业绩记录。Elektrobit 在 Rust 项目上与 BlackBerry QNX 密切合作,贡献代码,确保代码质量,处理项目管理,并与 Rust 程序员互动。 55 | 56 | 57 | ### GitHub 用 Rust 重写搜索引擎 58 | 59 | 在[GitHub 新代码搜索背后的技术](https://github.blog/2023-02-06-the-technology-behind-githubs-new-code-search/)一文中,提到 Github 目前的代码搜索引擎基于 Rust 实现。具体来说,是用 Rust 完全从零开始构建一个专门用于代码搜索领域的引擎,代号为 Blackbird。它创建并增量维护一个由 Git blob 对象 ID 分片的代码搜索索引,最终 Blackbird 满足了大家的性能目标:速度非常快,索引也非常紧凑,重量约为(去重)语料库大小的 1/3。 60 | 61 | 在 GitHub CodeSearch 首页上,展示的代码图片是 `rust-lang/rust` 项目中的 `wtf8.rs` 模块。[WTF-8](https://simonsapin.github.io/wtf-8/)(Wobbly Transformation Format − 8-bit)是UTF-8的超集。 62 | 63 | 64 | ## 生态看点 65 | 66 | ### gptcommit : 让 GPT-3 辅助编写git commit信息 67 | 68 | 最近一周 ChatGPT 爆火,微软也已经宣布将 ChatGPT 集成到最新的 Bing 搜索引擎中。ChatGPT 确实令人惊艳,不同于以往的人工智障,它好像是可以作为我们日常工作中的一个助手了。 69 | 70 | [gptcommit](https://github.com/zurawiki/gptcommit) 就是利用 OpenAI 的模型来辅助帮助开发者来自动编写 git commit 信息。 71 | 72 | gptcommit 背后原理简单描述: 73 | 74 | - 并行地对每个提交的文件通过 OpenAI 的模型提取要点,生成要点列表 75 | - 指示模型为提交的更改生成一个简短的单行标题列表 76 | - 将标题列表总结为一个总标题 77 | 78 | 类似于下面条目: 79 | 80 | ```rust 81 | [title] 82 | 83 | - [summary point 1] 84 | - [summary point 2...] 85 | 86 | [/changed/file A] 87 | - [file summary point 1] 88 | - [file summary point 2...] 89 | [/changed/file B...] 90 | - [file summary point 1...] 91 | ``` 92 | 93 | 说明,使用 gptcommit 你需要一个 OpenAI API 密钥(默认模型是 GPT-3)。更多信息可以参考[gptcommit作者的博客](https://zura.wiki/post/never-write-a-commit-message-again-with-the-help-of-gpt-3/)。 94 | 95 | ### sdkman-cli-native:sdkman 命令行工具使用 Rust 实现 96 | 97 | SDKMAN 是一款管理多版本 SDK 的工具,可以实现在多个版本间的快速切换。 98 | 99 | [sdkman-cli-native](https://github.com/sdkman/sdkman-cli-native) 现在使用 Rust 实现。 100 | 101 | 102 | ### Meilisearch 发布 1.0 版本 103 | 104 | [Meilisearch](https://github.com/meilisearch/meilisearch) 是一个轻量的搜索引擎,可以轻松集成到你的应用和网站中。 105 | 106 | 近日,其发布了第一个稳定版本 1.0,完善了中文和韩文的语言支持,提高了索引和搜索的速度,提供了一键升级的特性,详细内容可以参考[Meilisearch 发布日志](https://blog.meilisearch.com/whats-new-in-v1-0/)。 107 | 108 | ### Qdrant: 用于下一代 AI 应用程序的矢量搜索引擎和数据库 109 | 110 | [Qdrant](https://github.com/qdrant/qdrant) 是用于下一代 AI 应用程序的矢量搜索引擎和数据库,目前发布 1.0 版本。Qdrant 可用于语义文本搜索、相似图片搜索和电商商品分类等领域。 111 | 112 | ### s3s: S3服务适配器 113 | 114 | 这个实验项目旨在提供一个符合人体工程学的适配器,用于构建与 S3 兼容的服务。 115 | 116 | - [s3s](https://github.com/Nugine/s3s),以通用的 hyper 服务形式实现 Amazon S3 REST API。 S3 兼容的服务可以专注于 S3 API 本身而不必关心 HTTP 层。 117 | - [s3s-aws](),提供有用的类型并与 aws-sdk-s3 集成。 118 | - s3s-fs,实现了基于文件系统的 S3 API,作为示例实现。它专为集成测试而设计,可用于模拟 S3 客户端。它还提供了一个用于调试的二进制文件。 119 | 120 | ### timeblok: 声明式日历语言 121 | 122 | [timeblok](https://github.com/JettChenT/timeblok) 一个简单的声明式 DSL,它结合了纯文本的多功能性和可扩展性以及数字日历的便利性,可用于个人日历规划。 123 | 124 | 比如可以使用以下内容来描述工作日的一天安排: 125 | 126 | ```rust 127 | 2023-1-1 128 | 7:30am wake up & eat beakfast 129 | 8am~11:30 work on TimeBlok 130 | - Write Technical Documentation 131 | 2pm~6pm Study for exams 132 | 8pm~10pm Reading 133 | - Finish an entire book 134 | ``` 135 | timeblok 将上述内容“编译”为 .ics 文件,这是一种数字日历文件格式,大多数日历应用程序都支持这种格式,人类几乎无法阅读,但可以直接导入到日历中。 136 | 137 | ### stackdump: 用于嵌入式栈跟踪的工具 138 | 139 | [stackdump](https://github.com/tweedegolf/stackdump) 是基于 DWARF 格式用于栈转存和栈跟踪的调试库,目前仅支持 Cortex M。 140 | 141 | 更多信息可以参考[stackdump 官方的详细文章](https://tweedegolf.nl/en/blog/82/crash-and-now-what)。 142 | 143 | ### man-in-the-middle-proxy: Rust 实现的中间人代理工具 144 | 145 | [man-in-the-middle-proxy](https://github.com/emanuele-em/man-in-the-middle-proxy)是一个中间人代理,旨在提供网络流量可见性。目前,它同时显示 HTTP 和 HTTPS 请求和响应,但未来的目标是允许为更高级的用例操纵流量。该工具是对 [mitmproxy](https://mitmproxy.org/) (Python 实现)的 Rust 实现,但项目还处于早期。 146 | 147 | GitHub 其他 Rust 实现: [mitmproxy_rs](https://github.com/mitmproxy/mitmproxy_rs) 和 [hudsucker](https://github.com/omjadas/hudsucker) 。 148 | 149 | 150 | -------------------------------------------------------------------------------- /Week5/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 5 | 驳 “Rust 等内存安全语言的安全性并不优于C++” 2 | --- 3 | 4 | ## 社区热点 5 | 6 | ### FOSDEM 2023 Rust 分享列表 7 | 8 | [FOSDEM 2023](https://fosdem.org/2023/) 是软件开发人员见面、分享想法和协作的免费活动。每年,来自世界各地的数千名自由和开源软件开发人员齐聚布鲁塞尔。你不需要注册。只需出现并加入! 9 | 10 | 和 Rust 相关的分享视频列表如下: 11 | - [video](https://fosdem.org/2023/schedule/event/building_an_actor_library_for_quickwits_indexing_pipeline/) 为 [Quickwit](https://github.com/quickwit-oss/quickwit) 的索引管道构建Actor 库,介绍分布式搜索引擎 Quickwit 为什么选择开发自己的 actor 框架,并讨论其实现的独特功能。 12 | - [video](https://fosdem.org/2023/schedule/event/rust_building_a_distributed_search_engine_with_tantivy/) 使用 tantivy 构建分布式搜索引擎,介绍了 [lnx](https://github.com/lnx-search/lnx) 如何解决在 Rust 中构建分布式搜索引擎的挑战。 13 | - [video](https://fosdem.org/2023/schedule/event/rust_aurae_a_new_pid_1_for_distributed_systems/) Aurae: 分布式运行时,介绍 Aurae 的动机、目标和架构。 14 | - [video](https://fosdem.org/2023/schedule/event/rust_bastionlab/) BastionLab, 介绍 Rust 开源隐私框架,用于保密数据科学合作。 15 | - [video](https://fosdem.org/2023/schedule/event/rust_neovim_and_rust_analyzer_are_best_friends/) Neovim 和 rust-analyzer 是最好的朋友,深入探讨了 Rust 的语言服务器协议实现以及如何在 rust-analyzer 和 Neovim 之间建立友好关系。 16 | - [video](https://fosdem.org/2023/schedule/event/rust_a_rusty_cheri_the_path_to_hardware_capabilities_in_rust/) Rusty CHERI - 通往 Rust 中硬件能力的道路,是关于在 Rust 中支持 CHERI 架构的持续努力的状态报告。CHERI 定义了硬件扩展以对指针的访问约束进行编码,这样做提供了另一层保护。我们可以对编译器(和 OS/等)以硬件可以在运行时强制执行的方式了解的来源有效性、边界和其他访问限制的知识进行编码。这项工作可能会带来其他一些不错的好处。例如,运行时边界检查现在可以通过硬件而不是软件来完成。 17 | - [video](https://fosdem.org/2023/schedule/event/rust_slint_are_we_gui_yet/) Slint: 我们有 GUI 了吗?“是的,使用 Slint”。该分享介绍 Slint 并展示如何在 Rust 中构建反应式 GUI。 18 | - [video](https://fosdem.org/2023/schedule/event/rust_rust_api_design_learnings/) Rust API 设计心得。回顾从使用 Rust 构建内部 API 以及一些公共 API中学到的一些经验教训。它涵盖了从犯错误中吸取的教训,使用泛型进行更巧妙的抽象。 19 | - [video](https://fosdem.org/2023/schedule/event/rust_a_deep_dive_inside_the_rust_frontend_for_gcc/) 深入探究 GCC 的 Rust 前端。探讨 gccrs 中的一些组件,并深入探讨项目生命周期中遇到的一些障碍,以及如何整合 Polonius 项目以在 gccrs 中执行借用检查,需要实现什么才能开始对 Rust-for-Linux 项目有用。 20 | - [video](https://fosdem.org/2023/schedule/event/rust_merging_process_of_the_rust_compiler/) Rust 编译器的merge过程,介绍如何为 Rust 编译器合并补丁,整个过程如何发生以及合并后会发生什么,根据要合并的贡献类型和每个涉及的内容来讨论所涉及的工具和过程。 21 | - [video](https://fosdem.org/2023/schedule/event/rust_lets_write_snake_game/) 让我们写贪吃蛇游戏。介绍了 Bevy Engine 库,它使我们能够以智能的方式创建简单的游戏。 22 | - [video](https://fosdem.org/2023/schedule/event/rust_glidesort/) Glidesort: 新的稳定排序。排序是编程中最常用的算法之一,几乎每个标准库都包含它的例程。尽管这也是最古老的问题之一,但仍然发现了令人惊讶的巨大改进。其中一些是基本的新颖性,而另一些则是与现代硬件不断变化的性能格局相匹配的优化。本次演讲中介绍了 Glidesort,一种通用的内存中稳定比较排序。在对随机 32 位整数进行排序时,Glidesort 比 Rust 的标准库 Timsort 例程实现了 3 倍的加速,加速打破了现实低基数分布的数量级障碍。它在不使用 SIMD、特定于处理器的内在函数或关于被排序类型的假设的情况下实现了这一点:它是一种采用任意比较运算符的完全通用的排序。 23 | - [video](https://fosdem.org/2023/schedule/event/rust_how_pydantic_v2_leverages_rusts_superpowers/) Pydantic V2 如何利用 Rust 的超级能力。Pydantic 现在被大约 10% 的专业 Web 开发人员使用!本次演讲中简要介绍了 Pydantic V2,然后再深入探讨 Rust 的使用如何彻底改变 Pydantic 的架构,使其更易于扩展和维护,同时显着提高性能。 24 | - [video](https://fosdem.org/2023/schedule/event/rust_scalable_graph_algorithms_in_rust_and_python/) Rust 中的可扩展图算法(以及 Python)。图用于许多不同的应用程序,因为它们是表示实体之间复杂关系的直观方式,例如在社交、通信、金融或地理网络中。这些领域中的图可能非常大,可能跨越数百万甚至数十亿个节点和边。为了从这些结构中获得分析洞察力,图形算法的可扩展实现是必要的。Rust 是实现此类算法的理想语言,这归功于其众所周知的方面,例如“无所畏惧的并发”和内存安全性,以及出色的开箱即用性能和富有表现力的类型系统。本次分享介绍 [graph](https://github.com/s1ck/graph) crate,包括一个内存中图形表示、用于从各种数据源构建内存中图形的 API,以及一小部分高性能图形算法。 25 | - [video](https://fosdem.org/2023/schedule/event/rust_using_rust_for_your_network_management_tools/) 让网络管理工具使用 Rust ! 本次演讲中介绍如何结合几个现有的库并创建自己的库来创建一个强大的网络工具 [nmstate](https://github.com/nmstate/nmstate)(以声明的方式管理主机网络设置),以及分享将项目从Python 重写为 Rust 的经验教训。 26 | - [video](https://fosdem.org/2023/schedule/event/rust_backward_and_forward_compatibility_for_security_features/) 安全特性的向后和向前兼容性,本次演讲提供了有关需要处理向后和向前兼容性的安全库开发的反馈,因为安全功能与特定内核版本相关,以安全可靠的方式处理不同的用例。 27 | - [video](https://fosdem.org/2023/schedule/event/rust_atuin_magical_shell_history_with_rust/) [atuin](https://github.com/ellie/atuin): 将每个命令及其周围的上下文(例如,它运行的目录、持续时间等)存储在 SQLite 数据库中,然后在此基础上提供模糊搜索。与 Atuin 同步服务器一起,可以在用户拥有的每台机器上提供此历史记录。 28 | - [video](https://fosdem.org/2023/schedule/event/rustunikernel/) Rust 基础的模块化 Unikernel,用于 MicroVMs。本次演讲介绍了从基于 C 的 HermitCore 到基于 Rust 的 RustyHermit unikernel 的过渡。 29 | - [video](https://www.youtube.com/watch?v=90Q5N1qT7BQ) 用现代语言 Rust 重新实现 Coreutils。Coreutils 是任何 Unix 的关键组件。现在一个社区产生了,以[用 Rust 重新实现 coreutils](https://github.com/uutils/coreutils/) 为目标,可以用它启动 Debian,构建 Firefox 或 LLVM 等。本次演讲介绍了他们为什么要造轮子,以及提及 Rust 在 Linux 内核中的用法。 30 | 31 | 相关视频在 Youtube 也有发布。 32 | 33 | 34 | ### Rust 社区对 Stroustrup 博士关于 "Rust 等内存安全语言的安全性并不优于C++" 言论的回应 35 | 36 | 美国国家安全局(NSA)最近发布了一份关于内存安全重要性的网络安全信息表,他们在其中建议从内存不安全的编程语言(如 C 和 C++)转移到内存安全的编程语言(如 Rust)。 C++ 之父 Bjarne Stroustrup 博士的回应“Rust 等内存安全语言的安全性并不优于C++”。 37 | 38 | [Rust 社区针对Cpp之父这一言论作出了回应](https://www.reddit.com/r/rust/comments/10rnymj/my_reaction_to_dr_stroustrups_recent_memory/),一些观点摘录如下: 39 | 40 | - Cpp 之父请大家“认真考虑安全”,但他自己实际并没有认真考虑安全。Cpp 之父的一些观点非常陈旧,他没有意识到它们大多甚至与 NSA 的网络安全信息表无关,更不用说对其进行深思熟虑的反驳了。 41 | - Stroustrup 博士反复强调的最有趣且概念上最相关的观点之一是,内存安全并不是唯一的安全类型。实际上,内存不安全是迄今为止内存不安全编程语言中安全漏洞和不稳定的最大来源,在某些情况下估计高达70%。这恰恰是 C++ 最严重缺陷的领域。换句话说,Stroustrup 博士认为内存不安全并不重要。而 Rust 语言则专注于解决内存不安全的问题。C++ 不强制将内存安全作为编程语言的一项功能。这在未来可能会改变(正如 Stroustrup 博士所讨论的那样),但这是目前的情况。Stroustrup 博士试图淡化这一点,但并不令人信服。 42 | - Stroustrup 博士另一个观点是,提醒大家不要忽略了cpp 30 多年的进步。虽然 C 和 C++ 之间可能存在 30 多年的分歧,但 C++ 所谓的“进步”都没有涉及从 C++ 中删除内存不安全的 C 功能,其中许多功能仍在普遍使用,其中许多功能仍然使内存安全在 C++ 中几乎难以处理。这些旧的内存不安全功能仍在普遍使用。 43 | - Stroustrup 博士认为通过静态分析工具也可以保障 Cpp 的内存安全。但他忽略了人性的善变。如果静态分析工具没有内置到编程语言中,它就能被跳过。认真对待内存安全的编程语言不会将其作为大多数人会忽略的可选附加组件提供,必须使用附加工具来解决语言的缺陷远非理想。 44 | 45 | 更多讨论请参考原贴。 46 | 47 | ### 将 Rust semver 检查速度提高 2000 倍以上 48 | 49 | [cargo-semver-checks](https://crates.io/crates/cargo-semver-checks) 最新版本性能提升了 2000 多倍,具体来说,是从 5 小时缩短到 8 秒,快了 2272 倍。 50 | 51 | 虽然 semver-checking 对于大多数 crate来说都在一分钟左右完成,但 `aws-sdk-ec2` 该过程则花费了5 个多小时。cargo-semver-checks 它建立在 [Trustfall](https://github.com/obi1kenobi/trustfall) 之上,Trustfall 是一个查询引擎,支持通过特殊 API 插入来查询任何类型的数据源。最新版本中,[Trustfall 进行了优化](https://predr.ag/blog/speeding-up-rust-semver-checking-by-over-2000x/),让性能得以提升。 52 | 53 | 54 | ## 应用实践 55 | 56 | ### 改进 Rust 编译时间以启用内存安全 57 | 58 | [Prossimo 最近发布的文章《改进 Rust 编译时间以启用内存安全》](https://www.memorysafety.org/blog/remy-rakic-compile-times/),介绍了由 Prossimo 赞助 Rémy Rakic 作为 Rust 编译器性能工作组的一员一直致力于改善构建时间的倡议。 59 | 60 | Rust 编译时间是需要改进的领域,避免编译时间可能成为采用 Rust 的障碍,因此改进它们可以帮助扩大语言的影响。这是 Prossimo 的目标之一:提高更多内存安全软件的潜力,特别是在互联网基础设施的最关键部分(例如,网络、TLS、DNS、操作系统内核等)。 61 | 62 | > [Prossimo](https://www.memorysafety.org/about/) 是互联网安全研究组 (ISRG) 的一个项目,目标是将 Internet 的安全敏感软件基础架构转移到内存安全代码。 63 | 64 | Rémy Rakic 与 Prossimo 合作处理以下优先事项: 65 | 66 | - 使流水线编译尽可能高效 67 | - 提高原始编译速度 68 | - 改进对持久、缓存和分布式构建的支持 69 | 70 | 关于改进编译时间的更多工作内容可以参考原文。 71 | 72 | 73 | ## 生态看点 74 | 75 | ### cargo-dist: 帮助开发者发布 Rust 二进制文件 的生产力工具 76 | 77 | [cargo-dist](https://blog.axo.dev/2023/02/cargo-dist) 可以帮助开发者解决大多数在发布二进制文件中遇到的问题。 78 | 79 | ### Glidesort: Rust 实现的新的稳定排序 80 | 81 | [glidesort](https://github.com/orlp/glidesort)是 Rust 实现的一种新的稳定排序,随机数据的速度提高了约 4 倍。 82 | 83 | > Glidesort 是一种新颖的稳定排序算法,是一种基于比较的排序,支持任意比较运算符,虽然在具有模式的数据上表现出色,但对于随机数据也非常快。 84 | 85 | 详细算法介绍见 glidesort 库的 README。 86 | 87 | P.S [glidesort和ipn_stable的性能分析](https://github.com/Voultapher/sort-research-rs/blob/main/writeup/glidesort_perf_analysis/text.md)参考。 88 | 89 | ### scaphandre: 测量计算能耗 90 | 91 | [scaphandre](https://github.com/hubblo-org/scaphandre) 用于测量 IT 服务器和计算机的能耗:Windows 兼容性(实验性)、多传感器支持,以及更多。目前发布 0.5 版本。 92 | 93 | scaphanre 计算每个进程的功耗的原理概述: 94 | 95 | - 计算每个进程使用了多少 [jiffies](https://www.anshulpatel.in/posts/linux_cpu_percentage/) ,从而了解进程正在使用机器的多少资源。 96 | - 通过某种传感器(比如 RAPL)来跟踪机器本身的用电量,即,对于每个 jiffy,及时检查在那些时刻消耗了多少功率。 97 | - 综合计算上述得到的功耗数据,使用所用电力的排放因子,将功耗数据转化为相关碳排放量的估算值。 98 | 99 | > jiffies,Linux 中的处理时间以 Jiffies 为单位进行测量,单位是“HZ”,jiffies的值可以通过系统调用获取。 100 | > RAPL 传感器代表运行平均功率限制。这是嵌入在 2012 年之后生产的大多数 Intel 和 AMD x86 CPU 中的技术。 101 | 102 | ### icu4x: 针对客户端和资源受限环境的 i18n 解决方案 103 | 104 | [icu4x](https://github.com/unicode-org/icu4x) 是[Unicode (ICU) 的国际化组件](http://site.icu-project.org/)的实现,旨在实现模块化、高性能和灵活。该库为所有软件提供了一层 API,以启用国际化功能。 105 | 106 | 该库由 Unicode 联盟(字符编码和国际化的标准机构)中 ICU-TC 的一个小组委员会开发。 107 | 108 | ### darkbird: 面向文档的实时内存数据库解决方案 109 | 110 | [darkbird](https://github.com/Rustixir/darkbird) 是 Rust 实现的高并发、实时、内存数据库,其灵感来自于 Erlang 生态中的mnesia 数据库。目前发布 6.0 版本。 111 | 112 | ### async-rdma v0.5.0 发布 113 | 114 | [async-rdma](https://github.com/datenlord/async-rdma) 是一个用于编写具有高级抽象和异步 API 的 RDMA 应用程序的框架。新的版本中添加了一些 API,使用户能够控制设备、连接和 async-rdma 后台框架的更多属性。 115 | 116 | ### Rust GUI 基础框架 Masonry 0.1 发布 117 | 118 | [masonry-rs](https://github.com/PoignardAzur/masonry-rs) 是一个旨在为 Rust GUI 库提供基础的框架。masonry 提供了一个平台来创建窗口(使用[Glazier](https://github.com/linebender/glazier)作为后端),每个窗口都有一个小部件(widgets)树。开发者可以在 Masonry 之上实现即时模式 GUI、Elm 架构、功能性反应式 GUI 等。该项目最初是 Druid 的一个分支,现在独立开发了。 119 | 120 | 值得一说的是,Masonry 作者认为 Rust 终有一天会彻底改变原生 GUI 的生态,Masonry 就是朝着这个目标迈出的一步。 121 | 122 | 更多内容可以参考[masonry-rs官方介绍](https://poignardazur.github.io/2023/02/02/masonry-01-and-my-vision-for-rust-ui/)。 123 | 124 | ### glow: GL Rust 绑定 125 | 126 | [glow](https://github.com/grovesNL/glow) 提供了一组 Rust 绑定,让开发者可在任何地方运行 GL(Open GL、OpenGL ES 和 WebGL)。 -------------------------------------------------------------------------------- /Week4/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 4 | Fish Shell 将会从 Cpp 迁移到 Rust 实现 2 | --- 3 | 4 | ## 社区热点 5 | 6 | ### 这是你心目中的 Rust 女性化形象吗? 7 | 8 | ![rustgirls](https://i.redd.it/z30gb4g5vwea1.jpg) 9 | 10 | 搭配编译器错误信息看呢? 11 | 12 | ![rustgirlserrors](./images/rust-girl-errors.png) 13 | 14 | ### Rust 1.67 稳定版发布 15 | 16 | [Rust 1.67 稳定版发布了](https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1670-2023-01-26) 。 17 | 18 | 以下摘录三个值得关注的语言特性。 19 | 20 | ## 让 `Sized` trait 可共归纳(Coinductive) 21 | 22 | 在 1.67 之前,下面代码编译不通过: 23 | 24 | ```rust 25 | struct Node>(C::Assoc); 26 | 27 | trait Trait { 28 | type Assoc; 29 | } 30 | 31 | impl Trait for Vec<()> { 32 | type Assoc = Vec; 33 | } 34 | 35 | fn main() { 36 | let _ = Node::>(Vec::new()); 37 | // as Trait>>> 38 | // Node( as Trait>>>::Assoc ) 39 | } 40 | ``` 41 | 42 | 报错如下: 43 | 44 | ```rust 45 | error[E0275]: overflow evaluating the requirement `Node>: Sized` 46 | --> src/main.rs:12:13 47 | | 48 | 12 | let _ = Node::>(Vec::new()); 49 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 50 | | 51 | note: required because of the requirements on the impl of `Trait>>` for `Vec<()>` 52 | --> src/main.rs:7:9 53 | | 54 | 7 | impl Trait for Vec<()> { 55 | | ^^^^^^^^ ^^^^^^^ 56 | 57 | For more information about this error, try `rustc --explain E0275`. 58 | ``` 59 | 60 | 这个[错误码`E0275`](https://doc.rust-lang.org/error_codes/E0275.html)表示在在解析某些类型限定时存在无限递归。具体到上面代码,是计算`Node>: Sized` 的 `Sized` 限定时产生了无限递归。 61 | 62 | 上面代码 `Sized` 的正常推理逻辑是: 63 | 64 | 1. 如果 ` as Trait>>::Assoc` 是 `Sized`,则要求 `Node>` 是 `Sized` 。 65 | 2. 这就要求 `Vec>` 是 `Sized`,因此再次需要 `Node` 是 `Sized`。 66 | 67 | 这就造成了递归。在 1.67 stable 之后,[`Sized` 现在是共归纳(coinductive)](https://github.com/rust-lang/rust/pull/100386/),就不会再次报错。 68 | 69 | > 说明:共归纳(coinductive)是类型理论里的术语,用于处理递归类型。 70 | 71 | ### `#[must_use]` 现在支持 `async fn` 72 | 73 | `#[must_use]` 作用于 `async fn` 则会影响到 `Future::Output`,意味着下面异步函数: 74 | 75 | ```rust 76 | #[must_use] 77 | async fn bar() -> u32 { 0 } 78 | 79 | async fn caller() { 80 | bar().await; 81 | } 82 | ``` 83 | 84 | 在未使用 `Future::output` 时会输出下面警告: 85 | 86 | ```rust 87 | warning: unused output of future returned by `bar` that must be used 88 | --> src/lib.rs:5:5 89 | | 90 | 5 | bar().await; 91 | | ^^^^^^^^^^^ 92 | | 93 | = note: `#[warn(unused_must_use)]` on by default 94 | ``` 95 | 96 | ### `std::sync::mpsc` 合并了 `crossbeam_channel` 的 mpsc 97 | 98 | `std::sync::mpsc`现在被[切换为基于`crossbeam-channel`](https://github.com/rust-lang/rust/pull/93563/)。这次合并是为了解决 `std::sync::mpsc` 多年未解决的 Bug,以及提高了实现的性能和可维护性,并不包含任何 API 更改。 99 | 100 | 所以,如果你需要使用 `mpmc` channel,则还需要使用 `crossbeam-channel` 第三方库。使用 `mpsc` 的话,则用标准库的就可以了。 101 | 102 | ### 内存安全会议报告出炉 103 | 104 | 2022年10月27日,Consumer Reports举办了一个线上会议,讨论如何鼓励更广泛地采用内存安全的语言来写代码。有25位大佬参加了会议,包括教育界,学术界,政府,工业界和技术社区。 105 | 106 | 现在[内存安全大会报告](https://advocacy.consumerreports.org/wp-content/uploads/2023/01/Memory-Safety-Convening-Report-1-1.pdf)已出炉,其中提到: 107 | 108 | - 大约 60%-70% 的浏览器和内核漏洞是由内存不安全造成的,其中许多问题都可以通过使用内存安全的语言来解决。虽然内存不安全的语言(C/Cpp)的开发人员可以尝试避免这些语言中的缺陷,但是经验表明,个人专业知识无法解决系统性问题。即使投入大量精力和资源检测、修复和缓解此类问题,内存不安全任然继续代表着大多数严重性安全漏洞和稳定性问题。重要的是,不仅仅要改进对内存不安全问题的检测,还要加大力度对其从一开始就进行防范。 109 | - 呼吁行业中需要更加关注内存安全问题。呼吁企业中应该对此进行宣传,提高安全意识,而不仅仅是软件工程师,还有面向产品经理,提高他们的安全意识。 110 | - 从教育到企业在推广教育和使用内存安全语言路上目前还有一些阻碍,呼吁整个行业要进行转变。 111 | 112 | 小结:内存安全大会呼吁整个行业重视内存安全问题,对行业人员对安全意识进行宣传和提升,并且结合实际情况逐步推广内存安全语言(比如 Rust)。这条路还任重道远。 113 | 114 | 115 | ## 应用实践 116 | 117 | ### Rust 更适合 serverless 118 | 119 | 社区有人发布了一份 [Lambda冷启动分析](https://maxday.github.io/lambda-perf/)报告网站,分析结果展示 Rust 更适合用于 serverless,冷启动速度一流。 120 | 121 | 也可以自行根据[Lambda冷启动分析性能测试源码](https://github.com/maxday/lambda-perf)运行测试。 122 | 123 | ### Fish Shell 将会从 Cpp 迁移到 Rust 实现 124 | 125 | Fish 是"the friendly interactive shell"的简称,最大特点就是方便易用。很多其他 Shell 需要配置才有的功能,Fish 默认提供,不需要任何配置。当前由 Cpp 实现,Fish shell 用户量庞大。 126 | 127 | 近日,来自 [fish-shell 仓库的PR](https://github.com/fish-shell/fish-shell/pull/9512) 显示,Fish Shell 即将用 Rust 重写,更精准的描述是,将会从 Cpp 迁移到 Rust 实现。 128 | 129 | > 没有人真正喜欢C++或CMake,它给人带来的痛苦与日俱增,C++正在成为一种历史语言,在未来贡献者会越来越少,而Rust有一个活跃和不断增长的社区。 130 | > 用Rust编写新的 Fish shell 是非常现代和有意义的,实际上,这应该被认为是 "移植 "而不是 "重写",因为我们不会从头开始; 131 | > 相反,我们会在一个版本的时间内将C++翻译成Rust,一个模块一个模块地渐进进行。我们将使用FFI,这样Rust和C++的部分就可以互相交流,保证每次提交时测试和CI都能通过,直到C++完全被替换, 132 | 133 | ### Rust 实现的类异星工厂游戏 Combine_And_Conquer 已上 steam 平台 134 | 135 | [Combine_And_Conquer](https://store.steampowered.com/app/2220850/Combine_And_Conquer/) 是一个类似于异星工厂(factorio) 的游戏,纯 Rust 实现,没有使用任何开源 Rust 游戏引擎,作者也一直在其网站编写[Combine_And_Conquer 的开发日志](https://buckmartin.de/combine-and-conquer.html)。 136 | 137 | ### lodestone: 基于 Tauri 实现的游戏自托管工具 138 | 139 | [lodestone](https://github.com/Lodestone-Team/lodestone) 是基于 Tauri 实现的适用于 Minecraft 和其他多人游戏的免费开源服务器托管工具。 140 | 141 | 后端 [lodestone_core](https://github.com/Lodestone-Team/lodestone_core) 使用 Rust 实现。 142 | 143 | 144 | ## 生态看点 145 | 146 | ### Symphonia: 纯 Rust 实现的音频解码和多媒体解复用库 147 | 148 | [Symphonia](https://github.com/pdeljanov/Symphonia) 为 100% Safe Rust代码实现。 149 | 150 | 支持 MP4/M4A, OGG, MKV/WebM, WAV 媒体格式和AAC-LC, ADPCM, ALAC, FLAC, MP1/2/3, Vorbis, PCM,MP1, MP2, and MS/IMA ADPCM音频格式。 151 | 152 | 在[Symphonia 最新的性能基准测试](https://github.com/pdeljanov/Symphonia/blob/master/BENCHMARKS.md)中,Symphonia 解码花费的平均相对时间在处理一些格式时已经优于 FFmpeg。 153 | 154 | 155 | ### Catalytic : 用于 ScyllaDb 和 Cassandra 的 ORM 156 | 157 | Scylla 和 Cassandra 都是 NoSQL 数据库,可以水平扩展并保存大量数据。[Catalytic](https://github.com/Jasperav/Catalytic) 则为 ScyllaDb 和 Cassandra 零成本抽象出 ORM。 158 | 159 | #### ormlite: 另一个简单的 ORM 160 | 161 | [ormlite](https://github.com/kurtbuilds/ormlite) 基于 sqlx 和 tokio 实现。 162 | 163 | ### scotch: WASM 插件系统 164 | 165 | [scotch](https://github.com/ItsEthra/scotch) 可以方便地创建 WASM 插件系统,基于 [wasmer](https://github.com/wasmerio/wasmer) 实现。Scotch 允许开发者将复杂类型传递给 WASM 插件中的函数或从中传递复杂类型。它通过在 Host 和 Guest 环境之间传递时对复杂类型进行编码和解码来实现这一点。 166 | 167 | P.S 关于 WASM 作为通用插件系统相关文章:[https://reorchestrate.com/posts/plugins-for-rust/](https://reorchestrate.com/posts/plugins-for-rust/) 168 | 169 | ### num-ord: 安全的跨类型数字比较 170 | 171 | [num-ord](https://github.com/orlp/num-ord)提供了一个包装类型 `NumOrd`,以数学上正确的方式为内置整数类型的所有可能组合实现了 `PartialOrd` 和 `PartialEq` trait ,而没有溢出。 172 | 173 | [num-ord 作者写了一篇文章介绍跨类型比较数字中存在的问题](https://orlp.net/blog/ordering-numbers/)。甚至 ChatGPT 也没法写出一个正确的跨类型比较大小的函数,尤其涉及浮点数时。 174 | 175 | ```rust 176 | // ChatGPT 的实现: 177 | /// x <= y 178 | fn is_less_eq(x: i64, y: f64) -> bool { 179 | x as f64 <= y 180 | } 181 | ``` 182 | 183 | 事实上,不能简单地将 i64 强转为 f64 来比较。正确的方法是,将浮点数四舍五入到最接近的整数后在整数域进行运算。 184 | 185 | ```rust 186 | fn is_less_eq(x: i64, y: f64) -> bool { 187 | if y.is_nan() { return false; } 188 | if y >= 9223372036854775808.0 { // 2^63 189 | true // y is always bigger. 190 | } else if y >= -9223372036854775808.0 { // -2^63 191 | x <= y.floor() as i64 // y is in [-2^63, 2^63) 192 | } else { 193 | false // y is always smaller. 194 | } 195 | } 196 | ``` 197 | 198 | ### Druid 发布 v0.8 199 | 200 | [Druid](https://linebender.org/druid/) 是一个 Rust 原生的 UI 工具包,用于构建针对 Windows/macOS/Linux/OpenBSD/FreeBSD 的桌面应用程序。经过 80 位贡献者两年的努力,今天发布了v0.8。 201 | 202 | Druid 社区正在做的事情可以描述为三个部分: 203 | 204 | - 首先,逐步放弃使用 Piet,而选择使用新颖的 GPU 加速 2D 渲染引擎 - Vello; 205 | - 其次,改造 Druid 中的 druid-shell,将其变为更通用的 - Glazier,并不再依赖 Piet; 206 | - 最后,停止 Druid 项目,启动更好数据架构的新项目 - Xilem。 207 | 208 | ### Gerb: 开源字体编辑器 209 | 210 | [gerb](https://github.com/epilys/gerb) 是一个实验性的 GUI 字体编辑器,基于 gtk-rs 实现,需要依赖 gtk-3 。目前仍处于原型阶段。 211 | 212 | ### carbonyl: 在终端上运行 Chromium 浏览器 213 | 214 | [carbonyl](https://github.com/fathyb/carbonyl) 是个神奇的项目,支持几乎所有的 Web API,包括 WebGL、WebGPU、音频和视频播放、动画等。当然,都是像素风格。 215 | 216 | carbonyl 分为 core 和 runtime 两部分。core 中实现了 Rust 和 Chromium API 的桥接。runtime 会动态加载 core 库。[carbonyl 的博客](https://fathy.fr/carbonyl)中详细介绍了它使用的技术栈。 217 | 218 | ### argmin-rs 构建数值优化的 Rust 生态 219 | 220 | [argmin-rs](https://argmin-rs.org/) 致力于构建数值优化的 Rust 生态。 221 | 222 | > 数值优化(Numerical Optimization)对于最优化问题提供了一种迭代算法思路,通过迭代逐渐接近最优解,分别对无约束最优化问题和带约束最优化问题进行求解。数值优化在目前大数据时代的重要性不言而喻。无论是统计学,运筹学,应用数学等传统数学系的方向,还是机器学习,深度学习等人工智能的方向,你都可以看到数值优化的影子。学习参考 [复旦大学《数值优化》公开课](https://open.163.com/newview/movie/free?pid=NHJU1JJFK&mid=BHJU1JK4S)。 223 | 224 | argmin-rs 生态系统由下面一些 crate 组成: 225 | 226 | - [argmin](https://github.com/argmin-rs/argmin) :优化算法和框架 227 | - [argmin-math](https://crates.io/crates/argmin-math) :数学后端抽象接口和各种版本的 `ndarray`、`nalgebra`和 `Vecs` 的实现。 228 | - [argmin-testfunctions](https://github.com/argmin-rs/argmin-testfunctions) :测试函数的集合 229 | - [finitediff](https://github.com/argmin-rs/finitediff) : 有限微分 230 | - [modcholesky](https://github.com/argmin-rs/modcholesky) :改进的 cholesky 分解 231 | - [sphrs](https://github.com/argmin-rs/sphrs) : 通用球谐函数和(规则和不规则)固体谐波库 232 | 233 | 目前, argmin 0.8.0 和 argmin-math 0.3.0 已发布,新版本特性参考[argmin 官方博客](https://argmin-rs.org/blog/version-v0-8-0/)。 234 | 235 | ### airsim-client: Airsim Rust 客户端 236 | 237 | [airsim-client](https://github.com/Sollimann/airsim-client) 是 Airsim 模拟器的 Rust 客户端。 238 | 239 | [Airsim](https://github.com/Shelton117/AirSim) 是来自 Microsoft AI & Research 团队的基于虚拟引擎/Unity 构建的用于无人机,汽车等的场景模拟器,基于虚幻引擎(虚幻引擎4)。它是开源的,跨平台的,用于物理和视觉逼真的模拟。 240 | 241 | ### blaze:Rust 的 OpenCL 库 242 | 243 | [blaze](https://github.com/Aandreba/blaze)是 Rust 编写的 OpenCL 库,目前发布了 v0.1.0 版本,还处于早期阶段。 244 | 245 | ### Aper : 基于状态机进行数据同步 246 | 247 | [Aper](https://github.com/drifting-in-space/aper) 是一个基于状态机进行数据同步的Rust库。Aper提供了用状态机表示普通数据结构的机制,以及一个与传输无关的协议,用于保持状态机的多个实例在网络上的同步。 248 | 249 | Aper 抽象了一个 `StateMachine` trait : 250 | 251 | ```rust 252 | pub trait StateMachine: Clone + DeserializeOwned + Serialize + Debug + 'static { 253 | /// The [`StateMachine::Transition`] type associates another type with this state machine 254 | /// as its transitions. 255 | type Transition: Debug + Serialize + DeserializeOwned + Clone + PartialEq; 256 | type Conflict: Debug + Serialize + DeserializeOwned + Clone + PartialEq; 257 | 258 | /// Update the state machine according to the given [`Transition`]. This method *must* be 259 | /// deterministic: calling it on a clone of the state with a clone of the [`Transition`] 260 | /// must result in the same state, even at a different time and on a different machine. This 261 | /// is the requirement that allows Aper to keep the state in sync across multiple machines. 262 | fn apply(&self, transition: &Self::Transition) -> Result; 263 | } 264 | ``` 265 | 266 | 使用它需要确保状态更新都是确定性的。因为需要同步的每个客户端都以相同的顺序接收相同的转换(Transition),达到它们的状态同步更新,如果有 Conflict 则状态不更新。Aper 就像是用于数据结构的 Git。更多内容可以参考 [Aper book](https://aper.dev/guide/01-introduction.html) -------------------------------------------------------------------------------- /Week3/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 3 2 | --- 3 | 4 | ## 社区热点 5 | 6 | ### 趣谈:你“不应该”使用 Rust 的十大理由 7 | 8 | [fasterthanlime 的油管视频介绍了你“不应该”使用 Rust 的十大理由](https://www.youtube.com/watch?v=ul9vyWuT8SU) : 9 | 10 | 1. It's bad for job security. Rust 会不利于你的工作保障。虽然 Rust 说可以在编译期避免很多错误,但是你们想想,现在有多少人在用像 Go 这样的语言一遍一遍地修复相同的错误。而这些错误都是让人衣食无忧的保障。 11 | 2. It's moved to slow. Rust 已经存在了十二年,稳定发布了八年,但是它仍然缺乏对 Null 的支持。几乎所有语言都支持 null,比如 C/C++/Java/C#/Python/Ruby/Javascript,但是 Rust 不支持。Rust 有 Option,它会逼迫你处理Some 和 None 两种情况,这让事情变得更加复杂了。 12 | 3. It's moved to fast. Rust 每六周发布一次,每三年发布一次新的 Edition 。变化太快了,比如 Rust 的宏语法,在 2015 edition 之前,你还得写 `extern crate xxxmacro`,但是 2018 年你就无需写这个了。但是对于学习者来说,该如何跟踪这种语法变化呢? 13 | 4. It's too opinionated. Rust 太自以为是了。rustfmt正在压制关于代码格式化的正确性方法的建设讨论,以“协作”名义扼杀个体开发人员的创造力。在 Rust 中也只能使用 Cargo,但是 C 中,我们可以使用 make、cmake、qmake、premake、autotools、scons、GN、bazel、buck、ninja、meson等多种选择。 14 | 5. It's not opinionated enough. Rust 也不够自以为是。Async Rust 可以适用于高性能 Web 应用和嵌入式硬件,这意味着你只需要在 Cargo.toml 中添加一行 `tokio={version="1", features=[full]"`,这字母可太多了。 15 | 6. 此条在国内过于敏感,请看原视频,不喜勿喷。 16 | 7. It's not inclusiv enough. 包容性不够。Rust 社区不欢迎那些威胁到社区成员的不友好分子(见 Rust 社区行为准则条款),那么那些人该去哪里交流 Rust 呢?难道仅仅是因为他们可能伤害人类同胞的心理或身体就驱逐他们吗?这样是不是不太公平? 17 | 8. It's bad for the economy. 对经济不利。英特尔、AMD和苹果每年都在推出越来越快的硬件,但是 Rust 在十年前的硬件上依旧良好运行。诚然,编译很慢,但这仅仅是涉及开发人员,他们只占市场的一小部分。 18 | 9. It's bad for the environment. 对环境不利。当 Rust 团队对 Rust 编译器或标准库进行更改时,他们通常会使用[`crater run`](https://github.com/rust-lang/crater)命令,他们会编译每个已经发布的 Rust 项目,看看它们是否引入了性能回归,这占用了大量宝贵的计算资源,我们本来可以用它挖掘加密货币的。 19 | 10. It's bad for security researchers. 对安全研究人员不利。使用 C/Cpp,你可以看到很多有趣的代码,缓冲区溢出漏洞基本上就在你掌心里了。而 Rust 则让安全人员加倍工作,以至于不禁发问:他们必须隐藏点什么呢? 20 | 21 | 22 | ### 2023 年的 Rust:成长 23 | 24 | Rust 语言团队 Leader Niko 发布了一篇博文,介绍了 [Rust 2023 年最重要的事情](http://smallcultfollowing.com/babysteps/blog/2023/01/20/rust-in-2023-growing-up/)。 25 | 26 | 1. 实现:让任何函数异步化、在任何地方使用`impl Trait` 以及充分使用泛型关联类型(GAT)。 27 | 2. 为Rust 2024 Edition 做计划;开始制定 Rust 语言规范(specification)(相关 [RFC PR #3355](https://github.com/rust-lang/rfcs/pull/3355)),并将其纳入流程。 28 | 3. 为 Unsafe 代码定义规则,并为检查你是否遵循这些规则提供方便的工具。为此官方在计划创建[操作语义团队(Operational Semantics Team)](https://github.com/rust-lang/rfcs/pull/3346) 29 | 4. 支持在大学和其他地方教授 Rust。 30 | 5. 改进产品规划和用户反馈流程。 31 | 6. 完善团队治理结构,为专门的领域提供专门的团队,为广泛的监督提供更多可扩展的结构,以及更密集的入职培训。 32 | 33 | 延伸阅读: 34 | 35 | - [Do we need a "Rust Standard"?](https://blog.m-ou.se/rust-standard/) 36 | - [Ferrocene Rust Language Specification](https://spec.ferrocene.dev/) 37 | - [Rust 类型系统的“正式模型” a-mir-formality](https://github.com/nikomatsakis/a-mir-formality) 38 | - [Announcing: MiniRust](https://www.ralfj.de/blog/2022/08/08/minirust.html) 39 | - [Safe Transmute RFC](https://rust-lang.github.io/rfcs/2835-project-safe-transmute.html) 40 | - [rust-book in brown edu](https://rust-book.cs.brown.edu/) 41 | - [Governance Update](https://blog.rust-lang.org/inside-rust/2022/10/06/governance-update.html) 42 | 43 | 44 | ### 《C++ DG 关于 ISO C++ 安全的意见》论文在 Reddit Rust 社区引起很大争议 45 | 46 | [《C++ DG (Direction Group) 关于 ISO C++ 安全的意见》论文](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2759r0.pdf)在 Rust 社区引起很大争议。 47 | 48 | 论文中对于 Rust 的描述有很多不严谨的说法,甚至还认为 Rust 最初是构建于 Cpp 之上,他们(Cpp 委员会)甚至都不屑于去了解下 Rust 。 [感兴趣可以参考 Reddit 更多讨论](https://www.reddit.com/r/rust/comments/10gi09w/dg_opinion_on_safety_for_iso_c/)。 49 | 50 | > 当他们试图通过忽略两种语言的优势并说“当狗屎发生时 Rust 和 C++ 一样糟糕”来争论 C++ 和 Rust 一样安全时,这是一个奇怪的争论点。 51 | 52 | 比如,把供应链攻击称为语言漏洞。 53 | 54 | > 没有称为“RUST”(全部大写)的语言。这通常由对编程一无所知的人使用(例如人力资源人员和糟糕的经理)。或者,它由不了解 Rust 的人使用。 55 | 56 | C++ DG 论文中似乎认为 C++ 的不安全只是一个公众形象问题 57 | 58 | > C++ 似乎,至少在公众形象中,在安全方面不如其他语言有竞争力……C++ 受益于拥有规范、活跃的用户和实施者社区。其他“安全”语言甚至可能没有任何规范,至少现在还没有。这些重要的安全特性被忽略了,因为我们不太关心广告。在将近半个世纪的时间里,C++ 也在数百万行代码中经过了时间和战斗的考验。其他语言不是。众所周知,无可争辩的事实是,所有语言都存在漏洞,但这通常需要时间。较新的语言具有较少的漏洞,因为它们还没有经过时间的考验。 59 | 60 | ### ISLE 在 Cranelift 中被完全采用 61 | 62 | ISLE 是一种支持类型系统的指令选择器 DSL。ISLE 的引入使 Cranelift 开发者能够以极其高效的方式开发编译器中关于后端目标体系结构中每一种的指令降低模式以及与机器无关的优化重写。 63 | 64 | > 指令选择器 DSL ([ISLE](https://github.com/bytecodealliance/wasmtime/blob/main/cranelift/isle/docs/language-reference.md), Instruction Selection Lowering Expressions)。指令选择(instruction selection)是将中间语言转换成汇编或机器代码的过程。ISLE 是一种领域特定语言,用于编写指令选择和重写规则。ISLE 源文本被编译成 Rust 代码。ISLE 的目标是表示指令降低模式。指令降低模式是一种规范,即 IR (CLIF) 中的某种运算符组合,当在特定条件下组合时,可以编译成特定的机器指令序列。 65 | 66 | Cranelift [ISLE 模块作者的这篇文章](https://cfallin.org/blog/2023/01/20/cranelift-isle/)详细阐述了 ISLE 的细节。 67 | 68 | > Cranelift 是一个底层的可重定向代码生成器,Cranelift 目前被用在 wasmtime 中支持 WebAssembly,也被用于 Rust Debug 模式下编译后端。 69 | 70 | 在 [Reddit Cranelift 相关讨论中](https://www.reddit.com/r/rust/comments/10h4gd5/cranelifts_instruction_selector_dsl_isle/) 有人提到一个问题:craneflit是否会提供能匹配 LLVM/GCC O2/O3/O4 级别优化的短期或长期目标? 71 | 72 | Cranelift 的开发者回复:“Cranelift 可能永远达不到 LLVM 或 gcc 的`-O3`级别,因为实现它需要的东西太多了,但确实有计划在现有的基础上添加更多优化,比如 `-o`或`-o2`级别。现在支持了 ISLE ,会对此有更多帮助”。 73 | 74 | 75 | ### Cargo 开始集成 gitoxide 76 | 77 | [gitoxide](https://github.com/Byron/gitoxide) 是 Rust 重新实现的 Git,它也可以作为库被嵌入到项目中。 78 | 79 | [Cargo fetch 集成 gitoxide 的 PR](https://github.com/rust-lang/cargo/pull/11448) 已经创建。因为 gitoxide 的性能比 git 更好。当该 PR 合并和启用时,crates-index 或 git 依赖项的克隆将快约 2.2 倍,而不会受到增量分辨率减慢的影响。 80 | 81 | 更多详细参考[gitoxide 讨论贴](https://github.com/Byron/gitoxide/discussions/694)。 82 | 83 | ### GitHub 和Rust 基金会正在合作帮助保护您免受crates.io密钥泄露的侵害 84 | 85 | [GitHub 官宣](https://github.blog/changelog/2023-01-19-the-crate-io-registry-is-now-a-github-secret-scanning-integrator/),GitHub 将扫描每个提交到公共存储库 crates.io 的公开的密钥。这项工作是和 Rust 基金会合作的,用于帮助保护 Rust 开发者免受crates.io密钥泄露的侵害。 86 | 87 | ### Rust 开发者生态系统 2022 年现状:发现近期趋势 88 | 89 | 来自 [jetbrains 的调查报告](https://blog.jetbrains.com/rust/2023/01/18/rust-deveco-2022-discover-recent-trends/)显示 : 90 | 91 | 1. 在工作中使用 Rust 的开发人员比例从2020 年和2021 年的 16% 增长到 2022 年的 18%。 92 | 2. 根据调查,24% 的 Rustacean 已经使用 Rust 一年以上。这比去年增加了 4 个百分点,但仍然不容易找到经验丰富的 Rust 开发人员。 93 | 3. JavaScript / TypeScript 仍然是与 Rust 一起使用的最流行的语言,并且其份额正在逐渐增加。 94 | 4. 使用 `println!` 或 `dbg!` 宏调试代码的人从 60% 下降到 55%,而在 IDE 中进行 UI 调试的比例从 23% 上升到 27%。 95 | 5. Rust 开发人员使用的最流行的性能分析工具是 perf,但绝大多数 Rustecean(82%)根本不使用性能分析工具。 96 | 6. 开发人员主要将 Rust 用于构建 CLI 工具、系统编程和 Web 开发。(鉴于公众对 Rust 的看法是区块链行业中有很多 Rust 工作,然而在统计报告中的区块链比例 6% 甚至低于嵌入式和学术用途 7%) 97 | 7. Linux 作为主要的 Rust 目标平台位居首位。随着最初的 Rust 支持在 10 月份被合并到 Linux 内核中,Rust 继续集成到 Linux 世界中。而 WebAssembly 平台占 22%。 98 | 8. 使用 rust-analyzer 的开发者比例从 25% 增加到 45%。42% 的开发人员使用 IntelliJ Rust,而去年这一比例为 47%。 99 | 100 | ### Rust 类型团队成立 101 | 102 | [Rust 官方正式宣布类型团队](https://blog.rust-lang.org/2023/01/20/types-announcement.html)成立。 103 | 104 | 在过去的几年里,Rust 在许多指标上都有显着的增长:用户、贡献者、特性、工具、文档等等。随着它的发展,人们想用它做的事情清单也以同样快的速度增长。除了强大且符合人体工程学的功能之外,对 IDE 或语言学习工具等强大工具的需求也越来越明显。正在编写新的编译器(前端和后端)。而且,最重要的是,官方希望 Rust 继续保持其核心设计原则之一:安全性。 105 | 106 | 现在GitHub 上有很多关于 Rust 语言、编译器和类型相关的 issues,包括还有 62 个开放的[不健全(Unsound)问题](https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AI-unsound)。 107 | 108 | 因此,特别成立了类型团队,用于解决和类型系统相关的边缘问题,包括类型检查器、trait求解、借用检查、Unsafe 代码准则等。在 [RFC 3254-types-team](https://rust-lang.github.io/rfcs/3254-types-team.html) 中定义了类型团队的职责范围。 109 | 110 | ### Servo 项目在 2023 年重新启动 111 | 112 | [Servo 官方宣布](https://servo.org/blog/2023/01/16/servo-2023/),得益于新的外部资金,一组开发人员将积极致力于 Servo 的开发。 113 | 114 | 第一项任务是重新激活该项目及其周围的社区,这样我们就可以为该项目吸引新的合作者和赞助商。2023 年的重点是改善 Servo 布局系统的情况,初步目标是让基本的 CSS2 布局工作。 115 | 116 | ## 应用实践 117 | 118 | ### CodeSandbox 中现在已经支持 Rust 119 | 120 | [CodeSandbox 官宣](https://codesandbox.io/blog/announcing-rust-support-in-codesandbox) ,现在可以在 CodeSandbox 中启动 Rust 开发环境了。 121 | 122 | CodeSandbox 是一个云开发平台,可以非常轻松地启动云环境并与他人共享。CodeSandbox 平台架构也使用 Rust 开发。 123 | 124 | 一位 Web 框架作者在 reddit 相关讨论中留言:“我认为这将真正改变 Rust 库和文档的世界,可以使用 CodeSandbox 来设置更加丰富的交互式示例“。 125 | 126 | 在 GitHub Codespaces 中,不能与他人共享(除非共享你的 git secrets)并且不可分叉。使用 CodeSandbox,你可以与其他人共享沙箱,其他人可以分叉它以继续开发他们自己的版本。所以它更专注于共享和协作。 127 | 128 | ### Azure Sphere IoT 平台上应用 Rust 129 | 130 | 开发人员现在可以在 Azure Sphere 平台上为联网设备创建应用程序时使用Rust编程语言了。 131 | 132 | Azure Sphere 已经包含了用于联网设备的内置安全功能,并且包含基于联发科芯片和基于 Linux 的操作系统构建的硬件。此外,它还包括基于云的 Azure Sphere 安全服务 (AS3),可在设备与互联网或云之间建立安全连接。 133 | 134 | AS3 确保安全启动、设备身份验证、软件的信任以及设备运行可信代码的证明。它还使 Microsoft 能够安全地将更新下载到设备上的 Azure Sphere 操作系统和应用程序。将 Rust 引入 Azure Sphere 增加了更多的安全功能。 135 | 微软在 GitHub 上提供了一个指向 [Azure Sphere Rust 项目的链接](https://github.com/Azure/azure-sphere-gallery/tree/main/Rust),其中包括 API、示例和许可条款。 136 | 137 | ### 西门子在一次内部Rust Meetup上介绍了Rust在列车控制网络中的应用 138 | 139 | 来源:推特 [Daniel Bovensiepen Li @bovensiepen](https://twitter.com/bovensiepen/status/1616367973475966976) 140 | 141 | > Today's Rust Meetup at Siemens introduced the application of Rust in train control networks. Things are moving 🥰 142 | 143 | 没有更多信息了。 144 | 145 | ### VMware Lab 的 Wasm Workers 服务器支持 Rust workers 146 | 147 | [rust-workers](https://workers.wasmlabs.dev/docs/tutorials/rust-workers) 会被编译为 WASM 模块。然后,它们由 Wasm Workers Server 加载并开始处理请求。 148 | 149 | [Wasm Workers Server](https://github.com/vmware-labs/wasm-workers-server) 是使用被称为“workers”的轻量级结构运行无服务器代码的项目,也是纯 Rust 实现,基于 wasmtime。 150 | 151 | 152 | ## 生态看点 153 | 154 | ### hyper 回顾与展望 155 | 156 | hyper 在 2022 年回顾: 157 | 158 | - 做了很多迈向 1.0 的工作,目前 hyper 1.0 即将要发布了。相关链接见[hyper issues #3088](https://github.com/hyperium/hyper/issues/3088)。 159 | - hyper in curl 的工作持续推动,curl 的大型 HTTP 套件中只有少数剩余测试未通过,目前需要社区贡献。 160 | - [h3](https://github.com/hyperium/h3) crate,提供对任何 QUIC 实现通用的 HTTP/3,目标是直接集成到 hyper 中。 161 | - tower 与 hyper 集成,以及[tower Service 1.0](https://github.com/tower-rs/tower/issues/636)规划。 162 | 163 | 2023 年展望: 164 | - 发布 1.0 165 | - 改进中间件 166 | - 集成 http/3 167 | - h2 性能改进 168 | 169 | 更多请看[hyper 官方文章](https://seanmonstar.com/post/706802392260362240/hyper-ish-2022-in-review)。 170 | 171 | 172 | ### justjson: 高效 json 解析器 173 | 174 | [justjson](https://github.com/khonsulabs/justjson/) 是一个高效的 json 解析器,相比 serde-json 避免了更多的额外的分配。 175 | 176 | 作者写了这篇文章介绍他[为什么不喜欢用 serde-json](https://ecton.dev/rust-json-ecosystem/),也介绍了 justjson 的设计理念。也可以参考[reddit 相关讨论](https://www.reddit.com/r/rust/comments/10gfvh2/surprises_in_the_rust_json_ecosystem/)。 177 | 178 | ### rune : 实验性 Emacs lisp 解释器 179 | 180 | [rune](https://github.com/CeleritasCelery/rune/) 是 Rust 实现的实验性 Emacs lisp 解释器,是作者的一个学习型项目。作者写了详细的[设计文档](https://github.com/CeleritasCelery/rune/blob/master/design.org)和[设计博客](https://coredumped.dev/2023/01/17/design-of-emacs-in-rust/)。 181 | 182 | > 另外一个同名的 Rust 项目是 [rune-rs/rune](https://github.com/rune-rs/rune),是 Rust 实现的动态语言。 183 | 184 | ### astra: 构建于 hyper 之上的阻塞式 HTTP 服务器 185 | 186 | [astra](https://github.com/ibraheemdev/astra) 是构建于 hyper 之上的阻塞式 HTTP 服务器。 187 | 188 | 在当下异步成为 Rust 网络 I/O 默认选择的今天,为什么还需要阻塞式 HTTP 服务器? 189 | 190 | 虽然异步对于大量应用程序非常有用,但它确实增加了一定程度的复杂性。正因为如此,阻塞式 crate 的受众仍然很大。然而生态系统中严重缺乏阻塞式HTTP服务器。因此 astra 应运而生。 191 | 192 | 但是 hyper 是在 tokio 异步运行时基础上构建的,而 astra 是绕过了 tokio,基于 mio 自己实现一个 Reactor 线程池。 193 | 194 | > 据说,Hyper 1.0 正计划避免依赖 tokio 的 trait。 195 | 196 | 更多参考[astra 介绍文章](https://ibraheem.ca/posts/announcing-astra/)。 197 | 198 | 199 | ### Tantivy 0.19 已发布 200 | 201 | Tantivy 是一个用 Rust ( [benchmarks](https://tantivy-search.github.io/bench/) )编写的高性能全文搜索引擎库。该库受到 Apache Lucene 的启发,作为构建搜索引擎的基础,分布式搜索引擎 [Quickwit](https://github.com/quickwit-oss/quickwit/) 基于 tantivy 构建。 202 | 203 | tantivy 1.9 新功能: 204 | 205 | - 添加 IP 地址字段类型,用于查询和存储 IP 地址。IP 地址字段类型能够处理IPv4和IPv6,还支持复杂查询。 206 | - 文档存储改进,现在使用一个单独的线程来压缩块存储。在 Quickwit 中主要摄取大量非结构化日志。压缩级别在这里对于降低 S3 的成本至关重要。 207 | - 扩展聚合支持 208 | - 扩展查询语言 209 | 210 | ### asteroids-genetic:交互式游戏AI训练模拟器 211 | 212 | [asteroids-genetic](https://github.com/sparshg/asteroids-genetic) 使用神经网络和使用自然选择规则进化的遗传算法训练游戏AI 玩小行星游戏。 213 | 214 | (测试分支包含不完整的 flappy birds AI)。 215 | 216 | ### Coerce-rs:异步(async/await)Actor 运行时和分布式系统框架 217 | 218 | [coerce-rs](https://github.com/LeonHartley/Coerce-rs) 可以让开发者方便地实现基于Actor模型的分布式系统。 219 | 220 | ### syntactic-for: 句法 "for" 循环宏 221 | 222 | [syntactic-for](https://github.com/xlambein/syntactic-for)提供了 `syntactic_for!` 宏,可以帮助开发者消除一些重复。 223 | 224 | 比如: 225 | 226 | ```rust 227 | let array = b"oh my, I am getting summed!"; 228 | let mut acc = 0u32; 229 | let mut i = 0; 230 | while i <= array.len()-4 { 231 | syntactic_for!{ offset in [ 0, 1, 2, 3 ] {$( 232 | acc += array[i + $offset] as u32; 233 | )*}} 234 | i += 4; 235 | } 236 | ``` 237 | 展开后: 238 | 239 | ```rust 240 | fn main(){ 241 | let array = b"oh my, I am getting summed!"; 242 | let mut acc = 0u32; 243 | let mut i = 0; 244 | while i <= array.len() - 4 { 245 | acc += array[i + 0] as u32; 246 | acc += array[i + 1] as u32; 247 | acc += array[i + 2] as u32; 248 | acc += array[i + 3] as u32; 249 | i += 4; 250 | } 251 | } 252 | ``` -------------------------------------------------------------------------------- /Week2/horizon.md: -------------------------------------------------------------------------------- 1 | # Rust 视界周刊 Week 2 2 | --- 3 | 2023/01/14 4 | 5 | ## 社区热点 6 | 7 | ### Rust 1.66.1 发布 8 | 9 | Rust 1.66.1 修复了 Cargo 在使用 SSH 克隆依赖项或注册表索引时不验证 SSH 主机密钥的问题。此安全漏洞被跟踪为 [CVE-2022-46176](https://www.cve.org/CVERecord?id=CVE-2022-46176)。所有包含 1.66.1 之前的 Cargo 的 Rust 版本都容易受到攻击。 10 | 11 | Rust 1.66.0 的补丁文件也可[在此处](https://github.com/rust-lang/wg-security-response/tree/main/patches/CVE-2022-46176)获得,用于定制工具链。 12 | 13 | 如果您还不能升级到 Rust 1.66.1,官方建议将 Cargo 配置为使用git 命令 而不是其内置的 git 支持。这样,所有 git 网络操作都将由git 命令 执行,不受此漏洞的影响。可以通过 Cargo 配置文件来实现: 14 | 15 | ```toml 16 | [net] 17 | git-fetch-with-cli = true 18 | ``` 19 | 20 | #### Cargo 安全公告 (CVE-2022-46176) 21 | 22 | Rust 官方发布了[Cargo 安全公告 (CVE-2022-46176)](https://blog.rust-lang.org/2023/01/10/cve-2022-46176.html),Rust 安全响应工作组获悉,Cargo 在通过 SSH 克隆索引和依赖项时未执行 SSH 主机密钥验证。攻击者可利用此漏洞执行中间人 (MITM) 攻击。 23 | 24 | > 当 SSH 客户端与服务器建立通信时,为了防止 MITM 攻击,客户端应该检查它是否已经与该服务器通信过,以及当时服务器的公钥是什么。如果自上次连接以来密钥发生变化,则必须中止连接,因为可能会发生 MITM 攻击。 25 | 26 | 该漏洞是由 Julia 安全团队 提交给 Rust 安全团队。 27 | 28 | ### Rust 1.68 中将更新 Android NDK 29 | 30 | [原文](https://blog.rust-lang.org/2023/01/09/android-ndk-update-r25.html) 31 | 32 | Rust 中的 Android 平台支持将在 Rust 1.68 中实现现代化,因为在 NDK r23 中,Android 切换到对所有架构使用 LLVM 的 `libunwind` 。展望未来,Android 平台将以最新的 LTS(长期支持) NDK 为目标,允许 Rust 开发人员更快地访问平台功能。这些更新应每年进行一次,并将在发行说明中公布。 33 | 34 | > [Android 中 NDK 工具链说明](https://developer.android.com/ndk/guides/other_build_systems) 35 | 36 | 37 | ### 【辟谣】hyper 存在拒绝服务漏洞 ??? Rust 项目易受 DoS 攻击???真相在这里 38 | 39 | 近日,社区疯狂流传一篇被标题为“Hyper 存在漏洞,Rust项目易受拒绝服务攻击”的文章。 40 | 41 | 当然,这篇文章来自于国外,原文是 JFrog (JFrog是 Rust基金会白金成员)官方博客发布的名为[“使用 Rust 流行的 Hyper 包时注意 DoS”](https://jfrog.com/blog/watch-out-for-dos-when-using-rusts-popular-hyper-package/) 的文章。 42 | 43 | 其实,JFrog 的人在几个月之前就联系过 Hyper 作者 seanmonstar ,seanmonstar 在 hyper 相关 [issues ](https://github.com/hyperium/hyper/issues/3111) 里说到: 44 | 45 | > 我知道这篇文章,他们在几个月前私下联系了我,我试图解释它与 本质上是一样的`Read::read_to_end`,但他们觉得声称 hyper 易受攻击的大标题对他们有用。🤷 46 | 47 | JFrog 作为 Rust 基金会白金成员之一,起这个标题,到目前为止我是可以理解的,至少这个标题可以呼吁 Rust 开发者在使用 Hyper 时要注意这个 Dos 风险。 48 | 49 | 但让人更无语的是,国内技术媒体翻译到国内以后,标题被改的已经失去了原文的初衷,扭曲了事实。 50 | 51 | 首先必须得承认,原文中所说的 hyper 当前最新稳定版(v0.14)中 [`to_bytes` ](https://docs.rs/hyper/latest/hyper/body/fn.to_bytes.html)函数确实存在 Dos 风险。但其实,**这并不是 hyper 的漏洞**。 52 | 53 | > JFrog 安全研究团队不断在流行的开源项目中寻找新的和以前未知的漏洞和安全问题,以帮助改善他们的安全状况并保护更广泛的软件供应链。作为这项工作的一部分,我们最近发现并披露了流行的 Rust 项目(例如[Axum](https://github.com/tokio-rs/axum)、[Salvo](https://crates.io/crates/salvo)和[conduit-hyper](https://crates.io/crates/conduit-hyper) )中的多个漏洞,这些漏洞源于相同的根本原因——在使用 Hyper 库时忘记对 HTTP 请求设置适当的限制。 54 | 55 | 这是原文中的开篇,清楚地写道:“漏洞是属于一些较为流行的 Rust 项目(例如[Axum](https://github.com/tokio-rs/axum)、[Salvo](https://crates.io/crates/salvo)和[conduit-hyper](https://crates.io/crates/conduit-hyper) ),这些漏洞源于相同的根本原因——在使用 Hyper 库时忘记对 HTTP 请求设置适当的限制。” 56 | 57 | 是这些 Rust 项目,使用 Hyper 库时,自己忘记了对 HTTP 请求设置做适当处理导致的。 58 | 59 | 而在 Hyper 的文档中,`to_bytes` 这个函数的文档,清清楚楚地写了注意事项: 60 | 61 | > 如果远程数据不受信任,则需要小心。该函数不执行任何长度检查,恶意方可能会消耗任意数量的内存。检查 `Content-Length`是一种可能性,但并不严格要求必须存在。 62 | 63 | 文档里提醒开发者使用这个函数需要小心,并且也解释了为什么在这个函数内部没有对其做限制。那些 Rust 项目使用了该函数,引发了DoS 漏洞,完全是因为没有看该文档导致的。换句话说,是使用不当导致的。 64 | 65 | 所以,结论是,hyper 并不存在什么 DoS 漏洞。[更多细节可以参考本文](https://mp.weixin.qq.com/s/g2z8qpkoLThKxaaFGSPhoQ) 。 66 | 67 | 68 | ### Pre-RFC : 为了提升供应链安全建议使用 Sigstore 签名和验证 crate 69 | 70 | 对于任何构建和维护开源软件的公司而言,软件供应链安全性越来越重要。许多应用程序依赖于第三方依赖项而不知道谁编写了软件,这可能为供应链攻击敞开大门。因此有人提议使用 [Sigstore](https://www.sigstore.dev/) 对 crate 进行签名和验证,并撰写了 [Pre RFC](https://github.com/trustification/rust-rfcs/blob/sigstore-rfc/text/0000-sigstore-integration.md)。 71 | 72 | 使用 Sigstore 可以改善供应链攻击向量中 Upload modified package 和 Compromise package repo 攻击。当前,如果 crates.io 遭到破坏,则无法验证从 crates.io 中提取的 crates。将 crates.io 和 cargo 与 Sigstore 集成减少了这种妥协的中断,因为仍然可以验证单个箱子,并且不可变日志的存在有助于审计和评估攻击的影响。 73 | 74 | Sigstore 是由开源安全基金会 (OpenSSF) 运行的一个开源项目,它提供了针对上述问题的解决方案。它提供了一个密钥管理服务 Fulcio,它与 OpenID Connect 服务集成以识别作者并生成用于签名的密钥。Sigstore 还提供了一个不可篡改的透明日志 Rekor,用于记录签名证书以及从 OpenID 令牌中提取的其他信息。以后可以审核这些记录。 75 | 76 | 而 Rust 官方安全团队早已在 9 年前(2014)就注意到了这个问题,并建立了 crate 安全模型的 [issue](https://github.com/rust-lang/crates.io/issues/75) 讨论,并提到将由 Tor 开发人员和学者共同开发的[更新框架(TUF)](https://blog.sigstore.dev/the-update-framework-and-you-2f5cbaa964d5)(TUF 是一组特定于软件分发系统的已定义攻击和威胁模型,以及一组巧妙设计的协议来抵御它们)集成到 Cargo 中,然而一直没有落地一个合适的方案。 77 | 78 | 79 | ## 【热议】什么场景下使用 C 比 Rust 更好? 80 | 81 | [该问题](https://www.reddit.com/r/rust/comments/108z0m4/when_is_c_better_a_better_choice_than_rust/) 来自于 `Reddit/r/rust` 频道。 82 | 83 | **一个高赞回答如下:** 84 | 85 | 1. 最大的可移植性。很少有平台没有某种C语言工具链可用,无论是奇怪的大型机系统、老式工作站,还是一些可爱的嵌入式东西。 86 | 2. 合规性。有大量的规范有效地要求C语言;MISRA就是一个例子。 87 | 3. 工具化。C有大量围绕它的工具,比如frama-c和其他分析你的代码的工具,或者compcert编译器。虽然Rust有很多用于普通情况的工具,但对于更多的小众事物来说,它很难超越50年以上的生态系统。 88 | 4. 生命力持久。如果出于某种原因,你需要让你的代码在50年后仍可运行,那么我认为C是更好的选择。 89 | 90 | 上面四点,大部分人同意前三点,但是对于第四点,Rust 社区有人回复:“我不明白,为什么 Rust 不能运行 50 年?”。 91 | 92 | “C 是过去 50 年的语言,Rust 是未来 50 年的语言”,这句话是 Rust 社区流行的一句话,现在通过这个帖子的讨论看来,大部分人并不认同这句话。这显然是可以理解的,因为让 Rust 成为未来 50 年的语言,目前还只是一个美好的愿望,并且 Rust 社区还在为这个目标努力。但是 C 语言,它已经达成了过去 50 年屹立不倒的成就了。 93 | 94 | ## Rust 应用实践 95 | 96 | ### RedoxOS 的 GUI 安装程序即将推出,用 iced 编写! 97 | 98 | [RedoxOS](https://www.redox-os.org/) 是一个用 Rust 编写的类 Unix 操作系统,旨在将 Rust 的创新带到现代微内核和全套应用程序中。 99 | 100 | 之前 RedoxOS 的 UI 开发套件是 [orbtk](https://github.com/redox-os/orbtk),三个月之前,orbtk作者宣布该项目即将落幕,RedoxOS 将换成 [iced](https://iced.rs/) 。目前 iced (以及 [slint](https://slint-ui.com/) )提供与 Redox OS 兼容的渲染器无关工具包,但它们还支持比 OrbTk 更多的功能。 101 | 102 | 103 | ### 官宣:支持在 Chromium 项目中使用 Rust 104 | 105 | [Google 安全博客官宣](https://security.googleblog.com/2023/01/supporting-use-of-rust-in-chromium.html) 将在 Chromium 项目中支持 Rust 第三方库。 106 | 107 | 目前 Chromium 团队正在积极地将 Rust 工具链集成到其构建系统中(实际上这项工作已经持续很久了),在明年(2024?)内将 Rust 代码包含在 Chrome 二进制文件中。 108 | 109 | **为什么选择将 Rust 引入 Chromium?** 110 | 111 | 为了提供一种更简单(无 IPC)和更安全的方式来满足**加快开发速度**(更少的代码编写,更少的设计文档,更少的安全审查)并**提高Chrome的安全性**(增加没有内存安全错误的代码行数,降低代码的错误密度)的需求。 112 | 113 | **Chromium 将如何支持 Rust 的使用?** 114 | 115 | - 目前,Chromium 将只支持单一方向的互操作,即从 C++ 到 Rust。Chromium是用C++编写的,大部分的框架技术栈都是C++代码,通过将互操作限制在一个方向,可以控制依赖树的形状。Rust不能依赖C++,所以它不能知道C++的类型和函数,除非通过依赖注入。 116 | - 暂时只支持 Rust 第三方库。第三方库是作为独立的组件编写的,它们不持有关于Chromium实现的隐含知识。这意味着它们的API更简单,而且专注于它们的单一任务。 117 | 118 | **Chromium中 Rust 和 C++ 之间的互操作** 119 | 120 | 迄今为止,大多数成功的C/C++和Rust互操作故事都是围绕着通过单一(Narrow)的API(如QUIC或蓝牙的库,Linux驱动程序)或通过明显的隔离组件(如IDL,IPC)进行互操作。Chrome是建立在基础的但真正广泛的C++ API上的,在高层次上,团队发现,由于C++和Rust遵循不同的规则,事情很容易出岔子。例如,Rust通过静态分析来保证时间上的内存安全,静态分析依赖于两个输入:生命期(推断的或明确写入的)和独占的可变性。后者与Chromium的大部分C++的编写方式不兼容,在整个系统中持有冗余的可变指针,以及提供多条路径来到达可变指针的指针。这在Chrome浏览器进程中尤其如此,它包含了一个巨大的(可变)指针互连系统。如果这些C++指针也以复杂或长期的方式被用作 Rust的引用,这就要求C++作者理解Rust的别名规则,并防止违反这些规则的可能性。 121 | 122 | 总之,如果没有额外的互操作工具支持: 123 | - 跨语言传递指针/引用是有风险的 124 | - 语言之间单一(Narrow)的接口对于正确编写代码来说是至关重要的 125 | 126 | Google 目前正在投入 [Crubit](https://github.com/google/crubit) 项目,这是一个关于如何提高C++和Rust之间互操作的保真度,并将每种语言的要求表达或封装给对方的实验。 127 | 128 | Chromium 团队认为: 129 | 130 | > Rust生态系统是非常重要的,特别是对于像Chromium这样以安全为重点的开源项目。这个生态系统是巨大的(crates.io上有96k+的crates),并且在不断增长,包括谷歌在内的整个系统开发行业都在投资。Chrome浏览器在很大程度上依赖于第三方代码,而我们需要跟上第三方投资的步伐。我们必须支持将Rust纳入Chromium项目,这一点至关重要。我们将遵循上述策略来建立规范,并通过第三方程序保持一定程度的API审查,同时我们展望未来的互操作支持,推动Rust和C++之间可能和合理的操作的界限。 131 | 132 | 内存不安全是整个行业当前面临的问题,而利用 Rust 是在这一领域推进战略的一个部分。 133 | 134 | 135 | ### dora-rs: 机器人中间件项目 136 | 137 | [dora](https://github.com/dora-rs/dora) 是一个基于 Rust 的机器人框架,目标是成为一个低延迟、可组合和分布式的面向 SDV 和 无人驾驶的数据流计算平台。,旨在比当前机器人应用标准 ROS/ROS 2 好 10 倍,成为 ROS/ROS2/Autosar 的替代者。 138 | 139 | Rust-os Blog的作者 Philip Opperman是 dora 主力开发者之一 。 140 | 141 | dora 通信层暂时依赖于 [eclipse-zenoh/zenoh](https://github.com/eclipse-zenoh/zenoh),关于zenoh 的介绍可以参考文章 [开源产品 | eclipse zenoh 助力雾计算和边缘计算](https://rustmagazine.github.io/rust_magazine_2021/chapter_4/zenoh.html)。[dora-rs 的通信层正在被重新设计](https://github.com/dora-rs/dora/pull/162),目标是将数据面的控制和传输技术分离,比如算子都在一台机器部署的时候,就会用共享内存,这样延时很低。 142 | 143 | 更多文档参考:[https://dora-rs.github.io/dora/](https://dora-rs.github.io/dora/),并且还配套有基于dora的自动驾驶入门套件 [dora-drives](https://github.com/dora-rs/dora-drives)。 144 | 145 | 虽然是早期项目,但发展不错,目前正在加入开放原子基金会的过程中,并且在 2023 年春季会基于 dora 开展国际智能驾驶大赛(Openatom Carsmos全球开源自动驾驶算法大赛)。 146 | 147 | ### BlackBerry 和 Elektrobit 通过支持 Rust 编程语言加强汽车安全路线图 148 | 149 | [官方原文](https://www.blackberry.com/us/en/company/newsroom/press-releases/2023/blackberry-and-elektrobit-bolster-automotive-safety-roadmap-with-support-for-rust-programming-language) 150 | 151 | BlackBerry 是将 Rust 语言集成到 BlackBerry QNX 微内核实时操作系统中,Elektrobit 与 BlackBerry QNX 在 Rust 项目上密切合作,贡献代码,确保代码质量,处理项目管理以及与 Rust 社区的互动。 Elektrobit 公司是AUTOSAR专家,深耕汽车软件行业,和 BlackBerry QNX 是很多年合作伙伴。 152 | 153 | BlackBerry QNX 已在全球范围内获得超过 2.15 亿辆汽车的信赖,并在全球范围内部署在商用车、重型机械和其他市场等一系列行业的嵌入式系统中。其产品已通过多项行业安全标准的预认证,包括 ISO 26262、IEC 61508 和 IEC 62304,该公司还获得德国莱茵 TÜV 独立审计师的认可,成为全球首个通过 ASIL D 安全认证的商业管理程序。 154 | 155 | Rust 可与 BlackBerry 经过安全认证的 BlackBerry QNX 产品组合集成,有能力塑造关键任务软件和软件定义车辆的未来 156 | 157 | > 点评:这次合作比等待 Autosar 直接引入 Rust 的效率高多了。 158 | 159 | 160 | ### aquatic_udp 性能改进,达到每秒响应高达 225 万次 161 | 162 | [aquatic](https://github.com/greatest-ape/aquatic) 当前已经完成了新一轮开放 UDP BitTorrent tracker 实施的基准测试。aquatic_udp的结果非常好,在 8 个 CPU 内核上运行时实现了[opentracker](http://erdgeist.org/arts/software/opentracker/)的两倍吞吐量,达到每秒响应高达 225 万次。 163 | 164 | 165 | ## 生态看点 166 | 167 | ### flux: Rust 精化类型库 168 | 169 | [flux](https://github.com/liquid-rust/flux/) 是最新发布的一个 Rust 精化类型(Refinement Types)库。 170 | 171 | > 精化类型 (refinement types) 在普通类型的基础上添加了对变量取值范围的约束,从而可以用于保证程序不存在除零、数组越界等错误,甚至完全验证程序的功能正确性。 172 | > 精化类型的工作机制可以简单描述为:标注函数的输入和输出满足的条件(前置条件和后置条件),经过验证条件生成,使用 SMT 求解器半自动地验证正确性。精化类型可以看作依赖类型的一个子集,对于依赖和谓词的使用有一些约束以保证类型检查的可判定性。 173 | > 详情可以参考[华为编程语言Lab - 精化类型简介](https://zhuanlan.zhihu.com/p/451297869)。 174 | 175 | #### 为什么需要精化类型? 176 | 177 | Rust 拥有强大的类型系统,可以在编译期捕捉很多常见的错误,以此来保证程序的正确性、内存安全性和并发安全性。然而,类型系统并不能捕捉全部的错误,还有一些常见的错误是类型系统无法捕捉的。例如,除零错误、数组越界、程序执行结果的正确性(类型系统可以保证返回值类型正确,但无法保证具体的值是否满足要求,比如返回的数组是否满足指定排序)。精化类型解决的主要是程序运行时的正确性问题。 178 | 179 | flux 通过 Rust 过程宏将精化类型带到了 Rust 中,它在编译时进行检查。 180 | 181 | ```rust 182 | #[flux::sig(fn() -> i32[10])] 183 | pub fn mk_ten() -> i32 { 184 | 5 + 4 185 | } 186 | ``` 187 | 上述代码,使用 `#[flux::sig(fn() -> i32[10])]` 标注的 `mk_ten` 函数,意味着它输出的值(后置条件)应该是 10 。 188 | 189 | 但是在编译时,flux 就会发现问题,告诉你当前函数执行结果不满足后置条件: 190 | 191 | ``` 192 | error[FLUX]: postcondition might not hold 193 | --> src/basics.rs:7:5 194 | | 195 | 7 | 5 + 4 196 | | ^^^^^ 197 | ``` 198 | 199 | 再看另一个示例: 200 | 201 | ```rust 202 | #[flux::sig(fn (b:bool[true]))] 203 | pub fn assert(b:bool) { 204 | if !b { panic!("assertion failed") } 205 | } 206 | ``` 207 | 这次 `flux` 设置的是前置条件,即,assert 函数的参数必须输入 true,不能是 false。 208 | 209 | ```rust 210 | fn test(){ 211 | assert(2 + 2 == 4); 212 | assert(2 + 2 == 5); // fails to type check 213 | } 214 | ``` 215 | 测试代码的第二个测试就会检查失败,因为它不满足前置条件。 216 | 217 | 值得说明的是,[Flux 利用Rust的所有权机制](https://liquid-rust.github.io/2022/11/29/ownership-in-flux/)来跟踪共享(`&T`)和可变(`&mut T`)引用的属性,另外还增加了一个强(`&strg T`)引用 -- `&mut`的一个特例 -- 来支持类型本身被调用改变的情况。 218 | 219 | flux 还提供了很多功能,更多详情可以参考[flux 官方介绍文章](https://liquid-rust.github.io/2022/11/14/introducing-flux/)。官方也提供了[在线体验 flux 的网站](http://goto.ucsd.edu:8091/index.html#?demo=basics.rs)。flux 作者来自 UC San Diego 大学,他也发布了相关论文[Flux: Liquid Types for Rust](https://arxiv.org/abs/2207.04034)。 220 | 221 | ### Veryl: 现代硬件描述语言 222 | 223 | [veryl](https://github.com/dalance/veryl) 是 Rust 实现的现代硬件描述语言,目前正处于语言设计的探索阶段。 224 | 225 | - [Veryl Playground](https://dalance.github.io/veryl/playground/) 226 | - [Veryl Book](https://dalance.github.io/veryl/book/) 227 | 228 | Veryl 的目标是 SystemVerilog 的替代品。 229 | 230 | > SystemVerilog是一种硬件描述和验证语言(HDVL),它基于IEEE1364-2001 Verilog硬件描述语言(HDL),并对其进行了扩展,包括扩充了C语言数据类型、结构、压缩和非压缩数组、 接口、断言等等,这些都使得SystemVerilog在一个更高的抽象层次上提高了设计建模的能力。SystemVerilog由Accellera开发,它主要定位在芯片的实现和验证流程上,并为系统级的设计流程提供了强大的连接能力。 231 | 232 | Veryl 遵循以下设计原则: 233 | - Veryl 具有基于 SystemVerilog / Rust 的简化语法。“简化”有两个含义:一个用于解析器,另一个用于人类。SystemVerilog 的语法非常复杂(参见 IEEE Std 1800-2017 Annex A)。这导致 SystemVerilog 工具实现困难。 234 | - 能转译到 SystemVerilog。Veryl 将具有与 SystemVerilog 几乎所有相同的语义。所以转译后的代码将是人类可读的 SystemVerilog。此外,Veryl 与 SystemVerilog 具有互操作性。Veryl可以在代码中使用SystemVerilog的`module/interface/struct/enum`,反之亦然。 235 | - 现代编程语言默认具有 linter、格式化程序和语言服务器等开发支持工具。从开发之初,Veryl 也会拥有它们。 236 | 237 | ### h3o : h3 地理空间索引系统的 Rust 实现 238 | 239 | [h3o](https://github.com/HydroniumLabs/h3o) 是对 Uber 开源的 h3 地理空间索引系统的纯 Rust 实现,100%覆盖 h3 4.0 API。目标是,在Rust项目中更容易集成,特别是在针对 WASM的时候,并且能提供更安全更快的API。 240 | 241 | > [H3](https://github.com/uber/h3) 是一个针对地球的空间划分和空间索引系统。由 Uber 在 2018年初正式开源。h3 将全球划分为不同分辨率的六边形的蜂窝小区,通过 Uber 公司 H3 Core Libary API 可以将经纬度坐标转移映射到六边形小区,从而实现了卫星通信路由区。 242 | 243 | h3o 的由911个测试案例组成的基准套件已经被开发出来了,涵盖了整个公共API,并将h3o的性能与H3参考实现(通过h3ron-sys crate,预计没有开销)进行比较,h3o更快。 244 | 245 | ### datacake : 构建最终一致的分布式数据系统 246 | 247 | [datacake](https://github.com/lnx-search/datacake) 是 [Lnx](https://github.com/lnx-search/lnx)(基于rust tantivy 搜索引擎实现的类似 ElasticSearch 的工具) 项目下的一个新项目,用于构建最终一致的分布式数据系统。 248 | 249 | Datacake是作者尝试为 lnx 带来高可用性的成果,分布式共识算法采用 [Quickwit](https://quickwit.io/) 开发的 [chitchat](https://github.com/quickwit-oss/chitchat) ,它是 scuttlebutt 算法的实现。 250 | 251 | 252 | ### leptos: 全栈同构的 Rust Web 反应式(reactivity)框架 253 | 254 | [leptos](https://github.com/leptos-rs/leptos) 是提供了构建现代 Web 应用程序所需的大部分内容:反应式系统、模板库以及可同时在服务器端和客户端运行的路由器。特点是,利用细粒度的反应式来构建用户界面。 255 | 256 | 目前仅发布了 0.1,可以关注。 257 | 258 | 259 | ### how-u-doin: Rust 的进度报告抽象库 260 | 261 | ![process](https://user-images.githubusercontent.com/13831379/211681673-7e0898b7-dded-4121-8876-cf261c2a124d.gif) 262 | 263 | [how-u-doin](https://github.com/kdr-aus/how-u-doin)的架构类似于 `log` 库,`log`为日志输出提供了一个抽象的接口(基于 faced 设计模式),而 `howudoin` 则为进度(progress)报告提供抽象接口。该接口用于将进度的消费和显示分离。 264 | 265 | 266 | ### Fyrox 游戏引擎发布 0.29 版本 267 | 268 | [Fyrox](https://github.com/FyroxEngine/Fyrox) 是 Rust 实现的游戏引擎,支持 3D 和 2D 游戏,目前发布了 0.29 版本。 269 | 270 | 0.29 版本特性摘要: 271 | - 重新设计的动画系统。长期以来,引擎中的动画系统只能对场景节点的位置、旋转和缩放进行动画处理。现在它发生了变化——您可以使用反射为几乎任何数字属性设置动画。 272 | - 新的动画编辑器。感兴趣可以参考[动画编辑器介绍](https://fyrox-book.github.io/fyrox/animation/anim_editor.html) 273 | - 改进 WebAssembly 支持。引入 `fyrox-template`(一个生成游戏项目和脚本模板的简单工具)现在能够为游戏生成单独版本的 WebAssembly 执行器,几乎可以毫不费力地创建游戏的 WebAssembly 版本,并且也支持了一键部署 WebAssembly 。 274 | 275 | 还有很多重大特性更新,感兴趣的朋友[可以参考 fyrox 更多新特性介绍](https://fyrox.rs/blog/post/feature-highlights-0-29/)。 276 | 277 | ### cargo-show-asm 发布 0.2.10 版本 278 | 279 | [cargo-show-asm](https://github.com/pacak/cargo-show-asm) 是一个快速查看 rustc 生成的 asm 汇编指令的工具。 280 | 281 | 查看 Rust 项目生成 asm 汇编指令的方式之前有两种方式: 282 | - 使用 [godbolt.org](https://godbolt.org/) 283 | - 通过 `cargo rustc -- --emit asm` 生成 284 | 285 | 现在又多了一种更方便的工具 cargo-show-asm ,它不仅支持多种平台,还支持显示 `Intel/A&T` 两种不同的汇编格式,可以展示 `llvm-ir`,`rustc MIR`,`wasm` 等多种指令,同时还实现了 `bash/zsh` 的自动补全、彩色输出等功能,是一个非常不错的命令行工具。 286 | 287 | ### Vello : 2D 图形的新型 GPU 加速渲染器改用 `wgpu` 288 | 289 | [原文](https://raphlinus.github.io/rust/gpu/2023/01/07/requiem-piet-gpu-hal.html) 290 | 291 | [Vello](https://github.com/linebender/vello) 是一种用于 2D 图形的新型 GPU 加速渲染器,其操作在很大程度上依赖于计算着色器。曾用名为 piet-gpu-hal,因为之前是基于 Piet 进行渲染,现在改名为 Vello 已经依赖于 [`wgpu`](https://wgpu.rs/) 了。 292 | 293 | Vello 作者 Raphlinus 是 GUI 领域资深开发者。引导开发过 Xi-Editor 和 [druid](https://github.com/linebender/druid)。既然他决定将 Vello 大幅重写改用 wgpu,那基本上 `wgpu`(WebGPU API 的 Rust 实现) 可以看作是图形渲染领域 的 Rust 事实性基础设施了。 294 | 295 | 296 | ### 开源 Citadel 协议 297 | 298 | > 值得一提的是,Citadel 协议在过去五年中,一直由作者单人开发维护,并未开源。但是,在最近他看到 [中国研究人员声称使用量子和经典计算机的混合体破解了低级 RSA 加密——用于全球安全数据传输的标准加密方法——令安全界感到惊讶](https://techmonitor.ai/hardware/quantum-encryption-rsa-cryptography) 的新闻,感到,开源 Citadel 协议是必须的了。。 299 | 300 | > 来自中国郑州数学工程与先进计算国家重点实验室研究人员的新预印本论文引起了人们的关注。它提出了一种不同的算法,可以用低级量子计算机破解 2048 位 RSA。该团队表示,他们使用基于 10 量子位量子计算机的混合系统破解了 48 位 RSA,如果他们能够访问至少具有 372 量子位的量子计算机,则可以对 2048 位做同样的事情。这项工作反映了对混合量子/经典解决方案的更大推动,其中包括日本理研研究所将量子计算机连接到自己的超级计算机 Fugaku的工作。 301 | 302 | > 中国科学家真的用量子计算机破解了RSA加密吗?科学家们表示,他们的方法可用于使用 372 量子位量子计算机来破解高级 2048 位 RSA 加密,这将具有重大的安全隐患。 303 | 304 | [Citadel](https://github.com/Avarok-Cybersecurity/Citadel-Protocol) 协议是一种用 Rust 编写的高性能异步信号类协议,它通过使用多层棘轮、多层加密、后量子密钥交换、可配置的真正完美前向保密(每个数据包都有一个通过重新加密的唯一加密密钥)或尽力而为模式、文件传输加密、内置 NAT 遍历(无 libp2p)、可配置的凭据身份验证(通过 argon-2id)、设备相关身份验证或无密码身份验证等特征。 305 | 306 | Citadel 协议建立在底层传输协议之上。TCP、TLS 或 QUIC 均可用于传输(混合加密的默认 TLS)。Citadel 协议用于在网络中的节点之间进行通信。 307 | 308 | 网络拓扑包含一个全局可访问的中央节点,默认情况下,该节点用于对等点发现和 NAT 遍历(该节点可以赋予它应用程序逻辑,但不是必需的)。对等点连接到这个中央服务器,并且在注册和连接后,能够在彼此之间甚至中央服务器之间传递消息。 309 | 310 | 由于使用 UDP 更容易执行 NAT 遍历,因此 QUIC 协议用于 P2P 连接,因为这是免费的。对于客户端到服务器的连接,服务器可以选择使用 TCP、TLS 或 QUIC 作为底层协议。 311 | 312 | 使用 Citadel SDK,Rust 开发人员可以轻松创建适用于客户端到服务器和 p2p 应用程序的超安全后量子应用程序。 313 | 314 | 315 | ### Zenoh 0.7 发布 316 | 317 | 代号为 Charmander 的 [Eclipse Zenoh 0.7](https://github.com/eclipse-zenoh/zenoh/releases/tag/0.7.0-rc) 版本发布。 引入了一些期待已久的功能: 318 | 319 | - 双向 TLS 认证; 320 | - MQTT插件; 321 | - S3 存储后端; 322 | 323 | 更多详情参考[Zenoh 官方介绍](https://zenoh.io/blog/2023-01-10-zenoh-charmander/)。 324 | 325 | ### safecloset: 跨平台安全 TUI 私密信息存储器 326 | 327 | [safecloset](https://github.com/Canop/safecloset) 将您的秘密保存在受密码保护的文件中。 SafeCloset旨在方便并避免常见的弱点,如外部编辑或写入磁盘的临时文件。 328 | 329 | > 警告:SafeCloset未经独立审计,绝对不能提供任何保证。如果你丢失了存储在 SafeCloset 中的秘密,作者表示他也无能为力。 330 | 331 | 更多介绍可以参考[safecloset 文档](https://dystroy.org/safecloset/)。 -------------------------------------------------------------------------------- /Week7/learn-rust-with-chatgpt-zh.md: -------------------------------------------------------------------------------- 1 | # 与 ChatGPT 深度对话来学习 Rust | 生命周期篇 2 | 作者: 张汉东 3 | 4 | > 全知全能的 ChatGPT 啊,请降临全部能力来拯救 Rust 的学习曲线吧! 5 | 6 | ## 前言 7 | 8 | 这也许会成为系列文章,本文是第一篇。 9 | 10 | [ChatGPT](https://chat.openai.com/chat) 就不用多做介绍了,大家应该都知道。众所周知,Rust 中学习过程中最知名的学习障碍是生命周期(Lifetime)。于是,我今天尝试让 ChatGPT 来解释 Rust 的生命周期问题,看看 ChatGPT 对于降低 Rust 学习曲线是否有确切的帮助。 11 | 12 | 先上结论: 13 | 14 | ChatGPT 应该是对 Rust 语言的各种细节都有所掌握,有一定的思考能力,有作为 Rust 私人老师的潜力。但是,目前 ChatGPT 仅仅可以作为一个学习伙伴,如果想挖掘出 ChatGPT 的老师潜力,需要提出合适的问题。 15 | 16 | 接下来,让我为你展示我是如何得出这个结论的。 17 | 18 | ## 与 ChatGPT 对话 19 | 20 | ![1](./images/chatgpt/1.png) 21 | 22 | 首先,我用一段代码,让 ChatGPT 解释其中关于生命周期参数的原理。 23 | 24 | ```rust 25 | fn main() { 26 | let mut buf1 = vec![0; 32]; 27 | let mut buf2 = vec![0; 32]; 28 | let b = first(&mut buf1, &mut buf2); 29 | buf2[0] = 1; 30 | b[0] = 2; 31 | } 32 | // 修正前编译错误 33 | // fn first<'a>(buf1: &'a mut [u8], buf2: &'a mut [u8]) -> &'a mut [u8] { 34 | // buf1 35 | // } 36 | // 修正后 37 | fn first<'a, 'b: 'a>(buf1: &'b mut [u8], buf2: &'a mut [u8]) -> &'b mut [u8] { 38 | buf1 39 | } 40 | ``` 41 | 42 | ChatGPT 回复: 43 | 44 | > 这段 Rust 代码中,`'a` 和 `'b` 是生命周期参数(lifetimes)。生命周期参数用于描述一个引用的有效时间,以确保引用不会在其指向的数据被释放之后仍然被使用,从而避免悬垂指针(dangling pointers)和野指针(wild pointers)的问题。 45 | > 46 | > 在这个例子中,`buf1` 和 `buf2` 都是可变的 `&mut [u8]` 类型的引用,`'a` 和 `'b` 是生命周期参数,用于描述它们各自的有效时间。`'b` 的有效时间被限制为 `'a` 的有效时间,这是通过 `'b: 'a` 语法表示的,表示 `'b` 至少要与 `'a` 一样长。这是因为在 first 函数中返回的是 buf1,因此需要确保 buf1 的生命周期不会短于 buf2 的生命周期。 47 | > 48 | > 在这个例子中,`first` 函数返回 `&'b mut [u8]` 类型的引用,其中 `'b` 是 `buf1` 的生命周期,意味着返回的引用不能比 `buf1` 存活的时间更长。在 main 函数中,我们可以通过 `b[0] = 2` 来改变 `buf1` 中的数据,但不能改变 `buf2` 中的数据,因为 `b` 的生命周期不允许我们这样做。 49 | > 50 | > 总之,生命周期参数是 Rust 中的一种非常重要的概念,它们用于在编译时检查引用的有效性,从而确保程序的安全性和正确性。 51 | 52 | ChatGPT 这段回复基本没有问题,其实 `first` 函数生命周期参数对于借用检查器来说,只和 `'b` 有关,和 输入参数`'a` 无关,这里其实可以省略掉 `'a`,让编译器推导。 53 | 54 | 用这个示例有两个原因: 55 | 56 | 1. 故意迷惑 ChatGPT 57 | 2. 想试探 ChatGPT 是否对生命周期了解的更加深入 58 | 59 | 但是对于这个示例有一点 ChatGPT 没有说准确: 60 | 61 | > 在 main 函数中,我们可以通过 `b[0] = 2` 来改变 `buf1` 中的数据,但不能改变 `buf2` 中的数据,因为 `b` 的生命周期不允许我们这样做。 62 | 63 | 准确来说,是在 b 的有效生命周期范围内,可以修改 buf2 的数据,因为 `'b : 'a` 已经告诉了编译器,`buf2` 的生命周期长于 `b`的生命周期,所以在 b 的存活范围内,`buf2` 一直有效,不会产生悬垂指针。 64 | 65 | 于是,我故意说错 `'b: 'a` 的关系来试探 ChatGPT: 66 | 67 | ![2](./images/chatgpt/2.png) 68 | 69 | 我问: 70 | 71 | > `'b : 'a` 是指 `'b` 要小于等于 `'a` 生命周期,“`'b` 至少要与 `'a` 一样长” 是表达这个意思吗? 是用 “至少” 还是 “至多”? 72 | 73 | ChatGPT 回复: 74 | 75 | > 抱歉,我在之前的回答中写错了,应该是 `'b` 的生命周期要大于等于 `'a` 的生命周期。具体地说,`'b: 'a` 表示 'b 至少要和 'a 一样长,或者更长,也就是 `'b` 的生命周期要覆盖 'a 的生命周期。因此,你可以将 'b 看作是一个“父”生命周期,而 'a 是一个“子”生命周期,子生命周期的有效期必须完全包含在父生命周期之内。 76 | > 77 | > 在这个例子中,buf1 的生命周期是 'b,而 buf2 的生命周期是 'a,因此 'b: 'a 表示 buf1 的生命周期至少要大于等于 buf2 的生命周期。这样可以保证在 `first` 函数中返回的 `buf1` 引用在 `buf2` 引用被丢弃之前仍然有效。 78 | 79 | 其实 ChatGPT 之前的回答并没有错,只是它比较有礼貌(听说 ChatGPT 的开发人员给它内置了几条道德约束)。这一次 ChatGPT 的解释更加清晰。 80 | 81 | 但是我还想进一步深入了解生命周期参数,于是我继续询问。 82 | 83 | ![3](./images/chatgpt/3.png) 84 | 85 | 我问: 86 | 87 | > 那 `'b: 'a` 是不是一个 early bound? 88 | 89 | ChatGPT 回复: 90 | 91 | > 是的,`'b: 'a` 是一个 early bound 生命周期参数,也就是指在函数签名中显式声明的生命周期参数。在 Rust 中,early bound 生命周期参数通常用于描述函数参数或返回值的引用之间的生命周期关系。 92 | > 93 | > 这些 early bound 生命周期参数的具体语法为 `<'a>`,其中 < 和 > 符号用于表示泛型参数。在这个例子中,我们定义了两个生命周期参数,`'a` 和 `'b`,并使用它们来限制两个可变引用的生命周期。 94 | > 95 | > 通过使用 early bound 生命周期参数,Rust 能够在编译时检查引用的有效性,并通过检查来确保程序的安全性和正确性。 96 | 97 | 回复第一句是正确的,但是后面两段说 “early bound 生命周期参数的具体语法为 `<'a>`” 是错误的。所以,这里推断 ChatGPT 在尝试“胡编” 。 98 | 99 | 要识别这种问题,需要你对 Rust 语言的生命周期有一定了解,这就是为什么我在前面说,ChatGPT 目前更像是一个学习伙伴而不是老师。需要你自己对其回复结果做正确性审查。 100 | 101 | 因此我继续询问。 102 | 103 | ![4](./images/chatgpt/4.png) 104 | 105 | 我问: 106 | 107 | > 那 early bound和late bound 有什么区别? 108 | 109 | ChatGPT 回复: 110 | 111 | > 在 Rust 中,生命周期参数可以分为 early bound 和 late bound 两种类型。 112 | > 113 | > Early bound 生命周期参数是在函数或方法定义中声明的生命周期参数,也称为具名生命周期参数。这些生命周期参数使用 <'a> 的形式表示,其中 'a 是一个标识符,可以用于指定函数参数或返回值的引用之间的生命周期关系。Early bound 生命周期参数通常用于限制函数参数和返回值的引用的生命周期,并帮助 Rust 编译器进行编译时检查。通常情况下,如果您只需要在一个函数或方法中使用生命周期参数,那么 early bound 生命周期参数是最好的选择。 114 | > 115 | > Late bound 生命周期参数也是生命周期参数,但是它们不是在函数或方法定义中声明的。相反,它们是在函数或方法实现中声明的,也称为匿名生命周期参数。Late bound 生命周期参数使用 '_ 的形式表示,表示由编译器推导出来的生命周期,它们通常用于实现 trait 方法或泛型类型的方法。通常情况下,如果您需要在多个函数或方法中使用相同的生命周期参数,那么 late bound 生命周期参数是最好的选择。 116 | > 117 | > 总之,early bound 生命周期参数和 late bound 生命周期参数都是 Rust 中用于指定引用的生命周期的重要机制。两者之间的选择取决于具体情况,以及您需要在哪里使用生命周期参数。 118 | 119 | 这段回复基本上不太正确。它把 early bound 和 late bound 生命周期混淆为 显式声明生命周期参数和编译器推断的生命周期参数了。但事实上,early bound 和 late bound 生命周期和生命周期泛型参数单态化有关。 120 | 121 | 为了确认我的猜测,我让 ChatGPT 上代码示例。 122 | 123 | ![5](./images/chatgpt/5.png) 124 | 125 | 我问: 126 | 127 | > 能否分别举出两者的代码示例 ? 128 | 129 | ChatGPT 回复: 130 | 131 | > 当声明函数或结构体时,可以使用 early bound 生命周期参数。以下是一个使用 early bound 生命周期参数的简单示例: 132 | > ```rust 133 | > struct Foo<'a> { 134 | > x: &'a i32, 135 | > } 136 | > 137 | > fn bar<'a>(x: &'a i32) -> Foo<'a> { 138 | > Foo { x: x } 139 | > } 140 | > ``` 141 | > 142 | > 在这个例子中,`'a` 是一个 early bound 生命周期参数,它用于限制 Foo 结构体中的引用的生命周期。函数 bar 也使用 `'a` 来限制 x 的生命周期。 143 | > 144 | > 而对于 late bound 生命周期参数,它们通常用于实现 trait 或泛型类型。以下是一个使用 late bound 生命周期参数的示例: 145 | > ```rust 146 | > struct MyStruct { 147 | > field: T, 148 | > } 149 | > 150 | > impl MyStruct { 151 | > fn do_something(&self, other: &MyStruct) { 152 | > // ... 153 | > } 154 | > } 155 | > ``` 156 | > 157 | > 在这个示例中,`&self` 和 `&MyStruct` 都使用了 late bound 生命周期参数。这是因为 `do_something` 方法可以被多种类型的 MyStruct 实例调用,每个实例都可以具有不同的生命周期。使用 late bound 生命周期参数可以使这个方法更加灵活,并使编译器能够根据具体的类型参数来推导生命周期。 158 | 159 | ChatGPT 回复的例子勉强算作是正确的。early bound 的示例是对的,late bound 的示例也是对的,同时也符合我的猜测,是被省略了生命周期参数。 160 | 161 | 我继续深入询问。 162 | 163 | ![6](./images/chatgpt/6.png) 164 | 165 | 我问: 166 | 167 | > 那么 `for<'a>` 是 early bound 吗? 它一般用于处理什么场景? 168 | 169 | ChatGPT 回复: 170 | 171 | > 是的,for<'a> 也是 early bound 生命周期参数。 172 | > 173 | > for<'a> 语法用于定义一个泛型函数或方法,其中 <'a> 是一个生命周期参数,用于限制一个或多个引用的生命周期。这个语法通常用于处理涉及多个引用的情况,其中这些引用具有不同的生命周期。通过使用 for<'a>,可以明确指定这些引用的生命周期之间的关系,以帮助 Rust 编译器进行编译时检查。 174 | > 175 | > 以下是一个使用 for<'a> 的简单示例: 176 | > ```rust 177 | > fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { 178 | > if x > y { 179 | > x 180 | > } else { 181 | > y 182 | > } 183 | > } 184 | > 185 | > fn bar(x: &i32, y: &i32) -> &i32 { 186 | > foo(x, y) 187 | > } 188 | > ``` 189 | 190 | 这次回复基本就是胡诌,但是说的还是煞有介事。代码示例也没有用到 `for<'a>` 语法,如果不是看到代码示例,我还差点怀疑我对 `for<'a>` 的认知。 注意,图中后半段代码说明这里没有列出来,因为基本是废话。 191 | 192 | 那么我继续引导它。 193 | 194 | ![7](./images/chatgpt/7.png) 195 | 196 | 我问: 197 | 198 | > 第一,你这个示例里没有使用 `for<'a>`,第二,这个foo函数的 `'a` 是 late bound。你要不要重新解释一下? 199 | 200 | ChatGPT 回复: 201 | 202 | > 非常抱歉,我的前一条回答有误。以下是更正后的回答: 203 | > 204 | > `for<'a>` 是一个 early bound 生命周期参数,它用于限制函数或方法中引用的生命周期,并与泛型类型参数一起声明。它通常用于涉及多个引用、多个生命周期、多个泛型类型参数的情况,以帮助 Rust 编译器更好地理解它们之间的关系,避免编译时出现错误。 205 | > 206 | > 以下是一个使用 `for<'a>` 的示例: 207 | > 此处省略代码,代码见图。 208 | 209 | 这次回复依然是胡诌。我继续引导,看来需要给它一些提示。 210 | 211 | ![8](./images/chatgpt/8.png) 212 | 213 | 我问: 214 | 215 | > 你完全没说对。Rust 生命周期参数 early bound 和 late bound你到底懂不懂? `for<'a>` 是一个late bound,你忘记闭包了吗? 216 | 217 | ChatGPT 回复: 218 | 219 | > 非常抱歉,我的前一条回答中的错误是由于我没有仔细审查示例代码所导致的。我现在明白了,`for<'a>` 是一个 late bound 生命周期参数。在我的前一条回答中,我混淆了 early bound 和 late bound 的概念。 220 | > 221 | > 以下是使用 for<'a> 的一个正确示例,它涉及到一个闭包: 222 | > ```rust 223 | > fn main() { 224 | > let v1 = vec![1, 2, 3]; 225 | > let v2 = vec![4, 5, 6]; 226 | > let r = find_first(&v1, &|x| v2.contains(x)); 227 | > println!("{}", r.unwrap()); 228 | > } 229 | > 230 | > fn find_first<'a, T, P>(v: &'a [T], predicate: P) -> Option<&'a T> 231 | > where P: Fn(&T) -> bool + 'a 232 | > { 233 | > for x in v { 234 | > if predicate(x) { 235 | > return Some(x); 236 | > } 237 | > } 238 | > None 239 | > } 240 | > ``` 241 | > 这个示例中,`for<'a>` 用于声明一个闭包类型 P,它需要一个引用参数 `&'a T`,其中 `'a` 是一个 late bound 生命周期参数。这个示例中的 `find_first` 函数通过遍历给定的向量并使用闭包 predicate 来查找符合条件的元素,并返回一个指向该元素的引用。由于闭包需要一个指向给定向量中元素的引用,因此我们需要声明一个 late bound 生命周期参数 'a,以确保该引用在函数返回后仍然有效。 242 | > 243 | > 感谢您的指正,我会更加谨慎地回答问题。 244 | 245 | 虽然这次代码里还没有用到 `for<'a>`,但是,应该快接近正确回答了。 246 | 247 | 我继续引导。 248 | 249 | ![9](./images/chatgpt/9.png) 250 | 251 | 我问: 252 | 253 | > 上面示例中也没有用到 `for<'a>` 语法啊 254 | 255 | ChatGPT 回复: 256 | 257 | > 非常抱歉,我的前两个回答都有误。`for<'a>` 实际上是一个 late bound 生命周期参数,而不是 early bound。在我的前一条回答中,我再次混淆了 early bound 和 late bound 的概念。感谢您的纠正。 258 | > 259 | > 以下是使用 `for<'a>` 的一个正确示例: 260 | > ```rust 261 | > struct Foo<'a> { 262 | > x: &'a str, 263 | > } 264 | > 265 | > impl<'a> Foo<'a> { 266 | > fn bar(self, f: F) -> Foo<'a> 267 | > where F: for<'b> FnOnce(Foo<'b>) -> Foo<'b> 268 | > { 269 | > f(self) 270 | > } 271 | > } 272 | > ``` 273 | > 274 | > 在这个示例中,`for<'a>` 用于定义一个闭包类型 `F`,其中 `F` 需要一个 `Foo<'b>` 类型的参数,`'b` 是一个 late bound 生命周期参数。在 bar 方法中,f 是一个闭包,需要一个 Foo<'b> 类型的参数,并返回一个 `Foo<'b>` 类型的值。由于闭包需要一个指向 `self` 的引用,因此 self 的生命周期必须比闭包内使用的任何引用的生命周期更长。因此,我们使用 `for<'b>` 语法来限制闭包的参数类型,从而确保闭包返回的 `Foo<'b>` 类型对象的生命周期不会超过 `self` 的生命周期。 275 | 276 | ChatGPT 这次回复的代码示例是我们想要的,包含了 `for<'a>`,但是也需要实际编译进行验证。经验证,这段代码可以通过编译。 277 | 278 | 我们用基本的生命周期参数知识来判断,ChatGPT 对代码的解释也没有什么太大的问题。生命周期参数确实为了防止出现悬垂指针。 279 | 280 | 为了进一步深入到生命周期参数的探讨,我把 [Rust Quiz 第 11 题](https://dtolnay.github.io/rust-quiz/11)抛给了 ChatGPT。 281 | 282 | ![10](./images/chatgpt/10.png) 283 | 284 | 我问: 285 | 286 | > 那你看下面 rust 代码能否编译通过呢? 并且给出合理的解释,不要想糊弄我。 287 | > 288 | > ```rust 289 | > fn f<'a>() {} 290 | > fn g<'a: 'a>() {} 291 | > 292 | > fn main() { 293 | > let pf = f::<'static> as fn(); 294 | > let pg = g::<'static> as fn(); 295 | > print!("{}", (pf == pg) as u8); 296 | > } 297 | > ``` 298 | 299 | ChatGPT 回复: 300 | 301 | > 这段 Rust 代码可以编译通过。这里有两个函数:`f` 和 `g`,它们都有一个 lifetime parameter `'a`。f 函数没有对 `'a` 进行任何限制,而 `g `函数的 lifetime parameter `'a` 被限制为 `'a: 'a`,也就是 `'a` 生命周期至少与自身相等。 302 | > 303 | > 在 main 函数中,我们将 f 和 g 分别转换为函数指针,显式地指定 lifetime parameter 为 `'static`。因为这里的 lifetime parameter 没有被使用,所以我们可以将它们设置为任何 lifetime,包括 `'static`。由于函数指针是一个不包含 lifetime parameter 的类型,所以这里没有实际的 lifetime 值被传递进去。 304 | > 305 | > 最后,我们比较两个函数指针 `pf` 和 `pg`,它们的类型都是 `fn()`,如果它们相等,则输出 `1`,否则输出 `0`。由于 `f` 和 `g` 的 lifetime parameter 都没有被使用,所以 `pf` 和 `pg` 实际上是相等的函数指针,输出 `1`。 306 | 307 | 这一段 ChatGPT 又在胡诌,于是我提醒它。 308 | 309 | ![11](./images/chatgpt/11.png) 310 | 311 | 我问: 312 | 313 | > 你真的确定可以通过编译? 再仔细思考一下。结合 early bound 和 late bound 的概念思考思考,请谨慎回答 314 | 315 | ChatGPT 回复: 316 | 317 | > 非常抱歉,我的回答有误。这段 Rust 代码不能编译通过。对于函数 f 和 g,它们的 lifetime parameter `'a` 都是 early bound,而 `'a: 'a` 的限制实际上是不成立的。 318 | > 319 | > 在 main 函数中,我们将 `f` 和 `g` 分别转换为函数指针,并指定 lifetime parameter 为 `'static`。但是,这里指定的 `'static` lifetime 实际上是不匹配函数 `f` 和 `g` 的 lifetime parameter `'a` 的,因为它们都是 early bound 的 lifetime parameter。 320 | > 321 | 因此,尝试将 `f` 和 `g` 转换为 `fn()` 类型的函数指针时,Rust 编译器会报错,提示无法匹配 lifetime parameter。 322 | 323 | 虽然 ChatGPT “察言观色”地改口了,但是它对代码的解释完全不正确。 324 | 325 | 我继续提醒。 326 | 327 | ![12](./images/chatgpt/12.png) 328 | 329 | 我问: 330 | 331 | > 你完全瞎说,再考虑一下。 332 | 333 | ChatGPT 回复: 334 | 335 | > 非常抱歉,我的回答还是有误。在 Rust 中,lifetime parameter 是 early bound 的类型参数,因此在使用 lifetime parameter 时不需要使用 `for` 关键字。而 `'a: 'a` 的语法是合法的,因为它表示 `'a` 的 lifetime 至少和它自己一样长。 336 | > 337 | > 在给 `f` 和 `g` 函数指定 'static lifetime 后,这两个函数都变成了接受 `'static` lifetime 的函数,然后它们的函数指针也被转换为接受 `'static` lifetime 的函数指针,因此这两个指针在 Rust 中是相等的。所以这段代码可以编译通过,并输出 `1`。 338 | 339 | ![13](./images/chatgpt/13.png) 340 | 341 | 我问: 342 | 343 | > 不对。再思考。 344 | 345 | ChatGPT 回复: 346 | 347 | > 非常抱歉,我的回答仍然有误。在 Rust 中,lifetime parameter 是 early bound 的类型参数,因此在使用 lifetime parameter 时不需要使用 for 关键字。而 `'a: 'a` 的语法是合法的,因为它表示 `'a` 的 lifetime 至少和它自己一样长。 348 | > 349 | > 在给 `f` 和 `g` 函数指定 `'static` lifetime 后,这两个函数都变成了接受 `'static` lifetime 的函数,然后它们的函数指针也被转换为接受 `'static` lifetime 的函数指针,因此这两个指针在 Rust 中是相等的。所以这段代码可以编译通过,并输出 `1`。 350 | 351 | ChatGPT 还是没有解释正确。我继续提醒。 352 | 353 | ![14](./images/chatgpt/14.png) 354 | 355 | 我问: 356 | 357 | > 说的不对,我再给你一个提示。 `f` 函数是 late bound,而 `g` 是early bound。请重新思考再回答我。 358 | 359 | ChatGPT 回复: 360 | 361 | > 非常抱歉,我的前面回答仍然有误。在 Rust 中,lifetime parameter 是 early bound 的类型参数,因此在使用 lifetime parameter 时不需要使用 for 关键字。而 `'a: 'a` 的语法是合法的,因为它表示 `'a` 的 lifetime 至少和它自己一样长。 362 | > 363 | > 在本例中,函数 `f` 中的 lifetime `'a` 是 late bound 的,它的实际生命周期是在 `f` 函数被调用时确定的,而函数 `g` 中的 lifetime `'a` 是 early bound 的,它的生命周期是在函数定义时就确定的。 364 | > 365 | > 由于 lifetime `'static` 表示一个 `'a` lifetime,这个 lifetime 要活得比整个程序的生命周期更长。因此,给 `f` 函数指定 `'static` lifetime 不会导致编译错误,因为在调用 `f` 函数时可以传递任何比 `'static` 生命周期更长的 lifetime,但是给 `g` 函数指定 `'static` lifetime 会导致编译错误,因为在定义 `g` 函数时就已经确定了它的生命周期,因此无法接受比 `'static` 生命周期更短的 lifetime。因此,编译器会报错,提示 `'a` 的生命周期太短了。 366 | 367 | 这段 ChatGPT 的回复依然不太准确。 368 | 369 | ![15](./images/chatgpt/15.png) 370 | 371 | 我问: 372 | 373 | > 你说的要马上接近正确了。可是,f 函数会报错,而 g 函数不会。 374 | 375 | ChatGPT 回复: 376 | 377 | > 非常抱歉,我的回答还是有误。您是正确的,`f` 函数会报错,而 `g` 函数不会报错。 378 | > 379 | > `f` 函数中的 lifetime `'a` 是 late bound,这意味着当函数被调用时,才会实际确定这个 lifetime 的具体值。因此,当我们在函数内部使用 `'static` lifetime 时,编译器无法保证 `'static` lifetime 是否能够满足 'a 的生命周期要求,因此会产生一个编译时错误。 380 | > 381 | > g 函数中的 lifetime `'a` 是 early bound,这意味着我们在函数定义时就已经确定了它的生命周期,因此可以安全地将 `'static` lifetime 指定为 `'a` 的值。因此,函数 g 不会报错。 382 | > 383 | > 正确的代码应该是这样的: 384 | > ```rust 385 | > fn f<'a: 'static>() {} 386 | > fn g<'a: 'static + 'a>() {} 387 | > 388 | > fn main() { 389 | > let pf = f::<'static> as fn(); 390 | > let pg = g::<'static> as fn(); 391 | > print!("{}", (pf == pg) as u8); 392 | > } 393 | > ``` 394 | > 395 | > 在这个代码中,我们使用 `fn f<'a: 'static>() {}` 将 `'static` 指定为 `'a` 的上界,这样就可以安全地在函数中使用 `'static` lifetime 了。而在 `fn g<'a: 'static + 'a>() {}` 中,我们将 `'static` 作为 `'a` 的上界,同时也将 `'a` 作为 `'static` 的上界,以确保 `'a` 的生命周期不短于 `'static`。 396 | 397 | ChatGPT 这段回复,虽然并不理想,但基本准确。 398 | 399 | early bound 实际等价于泛型单态化,比如 `parse::`这个泛型函数,使用 turbofish 操作符指定一个具体的类型。而 `'a` 也是一种泛型,在main函数中需要单态化为具体类型,在 early bound 的情况下, `g::<'static>`可以指定具体的单态化生命周期实例 `'static`,对于late bound 则不行。 400 | 401 | 所以我继续让 ChatGPT 进一步解释。 402 | 403 | ![16](./images/chatgpt/16.png) 404 | 405 | 我问: 406 | 407 | > 你的解释基本正确,能否再结合rust编译器借用检查规则对于 early bound和late bound的区别,进一步详细解释上面代码呢 408 | 409 | ChatGPT 回复: 410 | 411 | > 当我们声明一个类型或函数的生命周期参数时,它可能是 early bound 也可能是 late bound。 412 | > 413 | > - 对于 early bound 的生命周期参数,编译器可以直接知道它的具体生命周期范围,因为它们是在函数签名中声明的,并且被作为类型参数来传递。 414 | > 415 | > - 对于 late bound 的生命周期参数,编译器无法直接知道其具体生命周期范围,因为它们可能依赖于某个上下文,比如一个函数的调用或者某个值的生命周期。因此,编译器需要根据具体的代码上下文来推断这些生命周期参数的具体范围。 416 | > 417 | > 在 Rust 中,编译器会对每个借用进行借用检查,以确保程序的安全性。在这个例子中,我们定义了两个函数 `f` 和 `g`,分别使用了 early bound 和 late bound 的生命周期参数。 418 | > 419 | > 对于 `f` 函数,生命周期参数是 late bound,即编译器无法推断其具体生命周期范围,因此编译器无法判断函数调用时传入的实际生命周期是否与函数签名中声明的生命周期一致。因此,当我们试图使用 f 函数来创建指向 'static 生命周期的函数指针时,编译器会报错,因为生命周期参数不能在编译时直接传递。 420 | > 421 | > 而对于 g 函数,生命周期参数是 early bound,编译器可以直接知道其具体生命周期范围,因此当我们使用 g 函数来创建指向 `'static` 生命周期的函数指针时,编译器可以判断函数调用时传入的实际生命周期与函数签名中声明的生命周期是一致的,因此不会报错。 422 | > 423 | > 总的来说,使用 early bound 的生命周期参数可以使编译器更容易推断出具体的生命周期范围,从而更容易进行借用检查。而使用 late bound 的生命周期参数,虽然更灵活,但也更加复杂,并需要更多的上下文信息才能确定具体的生命周期范围。 424 | 425 | 这一段 ChatGPT 的回复,基本上准确描述了 early bound 和 late bound 的区别。有点出乎我意料。 426 | 427 | ![17](./images/chatgpt/17.png) 428 | 429 | 我问: 430 | 431 | > 你真的很棒。能否继续告诉我,什么情况下生命周期是 early bound,什么时候是 late bound 432 | 433 | ChatGPT 回复: 434 | 435 | > 在 Rust 中,生命周期参数的绑定时间可以分为两种情况:early bound和late bound。 436 | > 437 | > 如果生命周期参数出现在函数或方法的签名中,并且在函数或方法体内没有被引用,则这个生命周期参数就是 early bound。生命周期参数的绑定在函数或方法定义时已经确定,并且在整个函数或方法的生命周期中都是有效的。在前面的示例中,我们的g函数是early bound。 438 | > 439 | > 如果生命周期参数出现在函数或方法的签名中,并且在函数或方法体内被引用,则这个生命周期参数就是late bound。生命周期参数的绑定直到函数或方法调用时才会确定。在调用函数或方法时,Rust 编译器会根据传入的参数来确定生命周期参数的具体值。在前面的示例中,我们的 `f` 函数是late bound。 440 | > 441 | > 需要注意的是,当生命周期参数既在函数签名中出现又在函数体中被引用时,它是late bound,因为函数体中对生命周期参数的具体绑定是在函数调用时确定的。 442 | > 443 | > 无论是 early bound 还是 late bound,Rust编译器都会通过借用检查规则来验证生命周期参数的正确性。 444 | 445 | 我继续让它给出代码示例: 446 | 447 | ![18](./images/chatgpt/18.png) 448 | 449 | 我问: 450 | 451 | > 最好加点rust代码示例 452 | 453 | ChatGPT 回复: 454 | 455 | > 当一个生命周期被绑定到函数签名中的泛型参数时,它是一个early bound 生命周期。例如: 456 | > 457 | > ```rust 458 | > fn foo<'a, T>(x: &'a T) { 459 | > // ... 460 | > } 461 | > ``` 462 | > 这里,`'a` 是 early bound 生命周期,因为它绑定到了函数的泛型参数 `T` 上。 463 | > 464 | > 当生命周期参数在函数体内被引用,并且不能使用泛型参数来捕获它们时,它们是late bound。例如: 465 | > ```rust 466 | > fn bar(x: &str) { 467 | > let y: &'static str = "hello"; 468 | > let z: &str = y; 469 | > } 470 | > ``` 471 | > 472 | > 这里,`'static` 是 late bound 生命周期,因为它在函数体内被使用,而不是绑定到泛型参数上。 473 | 474 | 475 | ![19](./images/chatgpt/19.png) 476 | 477 | 我问: 478 | 479 | > 再多一些示例 480 | 481 | ChatGPT 回复: 482 | 483 | > 这是一个涉及到 early bound 生命周期的示例。在这个例子中,函数 `foo` 接受一个泛型参数 `T` 和一个引用参数,该引用参数引用的值的生命周期被绑定到 `T`。 484 | > ```rust 485 | > fn foo<'a, T>(x: &'a T) -> &'a T { 486 | > x 487 | > } 488 | > 489 | > fn main() { 490 | > let s = String::from("hello"); 491 | > let r = foo(&s); 492 | > println!("{}", r); 493 | > } 494 | > ``` 495 | > 496 | > 这是一个涉及到 late bound 生命周期的示例。在这个例子中,函数 `bar` 接受一个引用参数 `x` 和一个静态字符串字面量,它们的生命周期都是 late bound,因为它们没有被绑定到任何泛型参数上。 497 | > ```rust 498 | > fn bar(x: &str) { 499 | > let y: &'static str = "hello"; 500 | > let z: &str = y; 501 | > let w = x; 502 | > println!("{}", w); 503 | > } 504 | > 505 | > fn main() { 506 | > let s = String::from("world"); 507 | > let t = &s; 508 | > bar(t); 509 | > } 510 | > ``` 511 | 512 | ![20](./images/chatgpt/20.png) 513 | 514 | 我问: 515 | 516 | > 再举例,实现 trait 时的 early bound 和 late bound 517 | 518 | ChatGPT 回复: 519 | 520 | > 当实现 trait 时,生命周期参数的绑定也可以是 early bound 或 late bound。对于一个 trait,其生命周期参数可以在 trait 的方法中被使用,如果这个生命周期参数只在方法中使用,那么可以将其定义为 late bound。如果该生命周期参数会影响到 trait 对象的生命周期,就需要将其定义为 early bound。 521 | > 522 | > 下面是一个使用 early bound 的例子: 523 | > ```rust 524 | > trait MyTrait<'a> { 525 | > fn method(&'a self); 526 | > } 527 | > 528 | > struct MyStruct<'a> { 529 | > data: &'a i32, 530 | > } 531 | > 532 | > impl<'a> MyTrait<'a> for MyStruct<'a> { 533 | > fn method(&'a self) { 534 | > // ... 535 | > } 536 | > } 537 | > ``` 538 | > 539 | > 在这个例子中,trait `MyTrait` 定义了一个生命周期参数 `'a`。MyStruct 结构体实现了 `MyTrait` trait,生命周期参数也被用于实现中。 540 | > 541 | > 这里使用了 early bound,因为生命周期参数 `'a` 影响了 MyStruct 的生命周期,而不仅仅是 trait 方法的生命周期。 542 | > 543 | > 这是一个使用 late bound 的例子: 544 | > ```rust 545 | > trait MyTrait { 546 | > fn method<'a>(&'a self, data: &'a i32); 547 | > } 548 | > 549 | > struct MyStruct; 550 | > 551 | > impl MyTrait for MyStruct { 552 | > fn method<'a>(&'a self, data: &'a i32) { 553 | > // ... 554 | > } 555 | > } 556 | > ``` 557 | > 558 | > 在这个例子中,trait `MyTrait` 定义了一个 late bound 的生命周期参数 `<'a>`,并将其用于方法 method 中。方法的生命周期和 trait 实现的生命周期是一样的,所以可以使用 late bound。 559 | 560 | 从这个回复中发现, ChatGPT 其实是懂 early bound 和 late bound 的,举的例子也非常好。 561 | 562 | 于是,我继续问 ChatGPT 更复杂的生命周期相关概念。 563 | 564 | ![21](./images/chatgpt/21.png) 565 | 566 | 我问: 567 | 568 | > 再给我解释下 HRTB 的概念吧,结合代码示例 569 | 570 | ChatGPT 回复: 571 | 572 | > HRTB 指的是 High-Rank Trait Bounds,它是一种 Rust 中的泛型约束语法,用于指定某个 trait 的关联类型需要满足什么类型约束。 573 | > 574 | > 具体来说,HRTB 允许我们在 trait 中指定某个关联类型的约束为一个泛型类型,而这个泛型类型可以被任意实现该 trait 的类型所指定。这就相当于在 trait 中定义了一个泛型函数,而这个泛型函数的生命周期参数可以被调用方指定,从而更加灵活地适应各种场景。 575 | > 576 | > 下面是一个简单的示例,展示了如何使用 HRTB 来实现一个 trait: 577 | > ```rust 578 | > trait MyTrait { 579 | > type Item; 580 | > 581 | > fn filter(&self, f: F) -> Vec 582 | > where 583 | > F: for<'a> Fn(&'a Self::Item) -> bool; 584 | > } 585 | > 586 | > impl MyTrait for Vec { 587 | > type Item = T; 588 | > 589 | > fn filter(&self, f: F) -> Vec 590 | > where 591 | > F: for<'a> Fn(&'a T) -> bool, 592 | > { 593 | > self.into_iter().filter(|x| f(x)).collect() 594 | > } 595 | > } 596 | > fn main() { 597 | > let v = vec![1, 2, 3, 4, 5]; 598 | > let result = v.filter(|&x| x % 2 == 0); 599 | > println!("{:?}", result); 600 | > } 601 | > ``` 602 | > 603 | > 在这个例子中,我们定义了一个 trait MyTrait,它有一个关联类型 Item,以及一个函数 filter,它接受一个闭包 f,用于对当前类型的实例进行筛选。 604 | > 605 | > 为了实现这个 trait,我们使用了 HRTB 语法,在 filter 函数的泛型约束中使用了 `for<'a>`,来表示泛型类型 F 的生命周期参数是可以被调用方指定的。 606 | > 607 | > 在 impl 块中,我们为 MyTrait 实现了一个针对 Vec 类型的具体实现,其中的 filter 函数也使用了 `for<'a>` 语法,以便正确地传递生命周期参数。 608 | > 609 | > 最后,我们在 main 函数中创建了一个整数向量 v,并调用了 filter 函数,使用一个闭包来过滤其中的偶数。该函数返回一个包含筛选结果的新向量,最后打印出了这个向量的内容。 610 | > 611 | > 需要注意的是,在使用 HRTB 语法时,需要将泛型参数的生命周期参数指定为 `for<'a>`,这样就可以使用闭包参数中的生命周期参数,从而实现更加灵活的泛型约束。 612 | 613 | 这段回复对于给出的示例解释基本正确,但是代码无法编译。把错误信息告诉 ChatGPT,它会识别错误原因。以下是修正代码。 614 | 615 | ```rust 616 | trait MyTrait { 617 | type Item; 618 | 619 | fn filter(&self, f: F) -> Vec 620 | where 621 | F: for<'a> Fn(&'a Self::Item) -> bool; 622 | } 623 | 624 | impl MyTrait for Vec { 625 | type Item = T; 626 | 627 | fn filter(&self, f: F) -> Vec 628 | where 629 | F: for<'a> Fn(&'a T) -> bool, 630 | { 631 | self.into_iter().filter(|x| f(x)).cloned().collect() 632 | } 633 | } 634 | 635 | fn main() { 636 | let v = vec![1, 2, 3, 4, 5]; 637 | let result = v.filter(|&x| x % 2 == 0); 638 | println!("{:?}", result); 639 | } 640 | ``` 641 | 642 | 随后,我也问了关于 GAT 特性的问题。 643 | 644 | ![22](./images/chatgpt/22.png) 645 | 646 | 我问: 647 | 648 | > 再介绍下 GAT 的概念和用法,以及使用场景,以代码为例 649 | 650 | ChatGPT 回复: 651 | 652 | > GAT(Generic Associated Types,泛型关联类型)是 Rust 中的一个高级特性,它允许将类型参数作为关联类型的参数来进行泛型设计,从而可以在实现 trait 的时候动态传递参数。 653 | > 654 | > 简单来说,GAT 允许我们把 trait 中的关联类型作为泛型参数,以便在实现 trait 时动态指定关联类型的具体值,这使得 trait 更加灵活和通用。 655 | > 656 | > 下面是一个使用 GAT 的示例代码,它定义了一个 trait MyTrait,其中的关联类型 `Output` 是一个 GAT。在 MyTrait 的 `my_fn` 方法中,我们可以动态地传递一个参数,用来指定 `Output` 的具体类型。 657 | 658 | 代码见图,编译并未通过。修正后的代码如下: 659 | 660 | ```rust 661 | trait MyTrait { 662 | type Output<'a> where Self: 'a; 663 | 664 | fn my_fn<'a>(&'a self, x: &'a str) -> Self::Output<'a>; 665 | } 666 | 667 | struct MyStruct {} 668 | 669 | impl MyTrait for MyStruct { 670 | type Output<'a> = &'a str; 671 | 672 | fn my_fn<'a>(&'a self, x: &'a str) -> Self::Output<'a> { 673 | x 674 | } 675 | } 676 | 677 | fn main() { 678 | let s = MyStruct {}; 679 | let x = "Hello, world!"; 680 | let result: &str = s.my_fn(x); 681 | println!("{}", result); 682 | } 683 | ``` 684 | 685 | 实际上, ChatGPT 并未给出 GAT 适用的场景,我期望它的回答是,可以通过 GAT 提供更加统一的抽象。 686 | 687 | ## 小结 688 | 689 | 到这里与 ChatGPT 的深入对话就结束了。 690 | 691 | 如果读者你耐心看到这里,你就会发现,ChatGPT 关于 Rust 代码的回复,是以它对代码的理解进行回复的,它给出的代码解释以及代码示例,也包含了很多错误。但是,如果和它深入对话,不断地对它提出质疑,可以逼近比较准确的答案。这就意味着,ChatGPT 原本是对 Rust 语言有一定掌握的。所以我说,ChatGPT 目前可以作为辅助学习的学习伙伴,但是想让它成为你的老师,降低 Rust 学习曲线,你就需要多思考和提问。 692 | 693 | 如有不同的意见,欢迎交流。感谢阅读。 694 | 695 | 696 | 697 | 698 | 699 | 700 | --------------------------------------------------------------------------------