├── .gitignore ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.md ├── assets ├── icons │ ├── Rust_programming_language_black_logo.svg.png │ ├── logo-xxxx.png │ ├── logo-xxxx.svg │ ├── logo.png │ └── logo.svg └── scss │ └── _variables_project.scss ├── config.yaml ├── content └── zh-cn │ ├── _index.md │ ├── books │ ├── _index.md │ └── rust-atomics-and-locks │ │ ├── 01-foreword │ │ └── _index.md │ │ ├── 02-preface │ │ └── _index.md │ │ ├── _index.md │ │ └── images │ │ └── cover.png │ ├── core │ ├── _index.md │ └── ops │ │ ├── _index.md │ │ ├── function │ │ ├── Fn.md │ │ ├── FnMut.md │ │ ├── FnOnce.md │ │ └── _index.md │ │ └── ops-module.md │ ├── docs │ ├── _index.md │ ├── build │ │ ├── _index.md │ │ ├── cargo │ │ │ ├── _index.md │ │ │ ├── cargo-book │ │ │ │ ├── _index.md │ │ │ │ ├── guide.md │ │ │ │ ├── images │ │ │ │ │ └── winapi-features.svg │ │ │ │ ├── reference-dependencies.md │ │ │ │ ├── reference-features.md │ │ │ │ ├── reference-manifest.md │ │ │ │ └── reference-workspaces.md │ │ │ ├── cargo.md │ │ │ └── settings.md │ │ ├── lints │ │ │ ├── _index.md │ │ │ ├── allowed-by-default.md │ │ │ ├── deny-by-default.md │ │ │ ├── groups.md │ │ │ ├── levels.md │ │ │ ├── lints.md │ │ │ └── warn-by-default.md │ │ ├── module │ │ │ ├── _index.md │ │ │ ├── images │ │ │ │ └── rust-module-system-explanation │ │ │ │ │ ├── rust-module-system-1.png │ │ │ │ │ ├── rust-module-system-2.png │ │ │ │ │ ├── rust-module-system-3.png │ │ │ │ │ ├── rust-module-system-4.png │ │ │ │ │ └── rust-module-system-5.png │ │ │ ├── learn-rust-module.md │ │ │ ├── rust-module-system-explanation.md │ │ │ └── rust-programming-langurage │ │ │ │ ├── _index.md │ │ │ │ ├── bringing-paths-into-scope-with-the-use-keyword.md │ │ │ │ ├── defining-modules-to-control-scope-and-privacy.md │ │ │ │ ├── module-system.md │ │ │ │ ├── packages-and-crates.md │ │ │ │ ├── paths-for-referring-to-an-item-in-the-module-tree.md │ │ │ │ └── separating-modules-into-different-files.md │ │ ├── rustc │ │ │ ├── _index.md │ │ │ ├── command-line-arguments.md │ │ │ └── conditional-compilation.md │ │ └── rustup │ │ │ ├── _index.md │ │ │ ├── rustup-book.md │ │ │ └── rustup.md │ ├── grammar │ │ ├── _index.md │ │ ├── basic │ │ │ ├── _index.md │ │ │ ├── comment.md │ │ │ ├── const.md │ │ │ ├── expression.md │ │ │ ├── print.md │ │ │ ├── return.md │ │ │ ├── statement.md │ │ │ └── variable.md │ │ ├── collection │ │ │ ├── _index.md │ │ │ ├── binaryheap.md │ │ │ ├── deque.md │ │ │ ├── linkedlist.md │ │ │ ├── map.md │ │ │ ├── set.md │ │ │ └── vec.md │ │ ├── flowcontrol │ │ │ ├── _index.md │ │ │ ├── for-in.md │ │ │ ├── if-let.md │ │ │ ├── if.md │ │ │ ├── index (另一个副本).md │ │ │ ├── loop.md │ │ │ ├── match.md │ │ │ └── while.md │ │ ├── grammar.md │ │ ├── pointer │ │ │ ├── _index.md │ │ │ ├── fn.md │ │ │ ├── pointer.md │ │ │ ├── raw-pointer.md │ │ │ ├── reference.md │ │ │ └── smart.md │ │ ├── string │ │ │ ├── _index.md │ │ │ ├── str.md │ │ │ └── string.md │ │ └── type │ │ │ ├── _index.md │ │ │ ├── array.md │ │ │ ├── bool.md │ │ │ ├── char.md │ │ │ ├── enum.md │ │ │ ├── float.md │ │ │ ├── integer.md │ │ │ ├── never.md │ │ │ ├── range.md │ │ │ ├── slice.md │ │ │ ├── struct.md │ │ │ └── tuple.md │ ├── installation │ │ ├── _index.md │ │ ├── cargo │ │ │ ├── images │ │ │ │ └── cargo-proxy.png │ │ │ └── index.md │ │ ├── linux │ │ │ └── index.md │ │ ├── upgrade │ │ │ └── index.md │ │ └── windows │ │ │ └── index.md │ ├── introduction │ │ ├── _index.md │ │ ├── edition.md │ │ └── information.md │ ├── ownership │ │ ├── _index.md │ │ └── rust-bczd.md │ └── type │ │ ├── _index.md │ │ ├── concept │ │ ├── _index.md │ │ └── rust-bczd.md │ │ ├── convert │ │ ├── Deref │ │ │ ├── _index.md │ │ │ └── rust-bczd.md │ │ ├── From │ │ │ ├── _index.md │ │ │ └── rust-bczd.md │ │ ├── Into │ │ │ └── _index.md │ │ ├── _index.md │ │ └── as │ │ │ ├── _index.md │ │ │ └── rust-bczd.md │ │ ├── generic │ │ ├── _index.md │ │ ├── generic.md │ │ └── rust-bczd.md │ │ ├── overview │ │ ├── _index.md │ │ ├── derivation │ │ │ ├── _index.md │ │ │ └── rust-bczd.md │ │ └── size │ │ │ ├── _index.md │ │ │ └── rust-bczd.md │ │ ├── trait │ │ ├── _index.md │ │ ├── rust-bczd.md │ │ ├── trait-object │ │ │ ├── _index.md │ │ │ └── trait-object.md │ │ └── trait.md │ │ └── type.md │ ├── featured-background.jpg │ ├── search.md │ └── std │ ├── _index.md │ ├── async │ ├── _index.md │ └── async.md │ ├── borrow │ ├── _index.md │ └── borrow.md │ ├── boxed │ ├── _index.md │ └── boxed.md │ ├── cell │ ├── _index.md │ └── cell.md │ ├── clone │ ├── _index.md │ └── clone.md │ ├── collections │ ├── _index.md │ └── collections.md │ ├── marker │ ├── _index.md │ ├── copy │ │ ├── _index.md │ │ ├── rust-bczd.md │ │ ├── source.md │ │ └── std-doc.md │ ├── send │ │ ├── _index.md │ │ ├── nomicon-send-and-sync.md │ │ ├── rust-bczd.md │ │ ├── source.md │ │ └── std-doc.md │ ├── sized │ │ ├── _index.md │ │ ├── rust-bczd.md │ │ ├── source.md │ │ └── std-doc.md │ ├── sync │ │ ├── _index.md │ │ ├── source.md │ │ └── std-doc.md │ ├── unpin │ │ ├── _index.md │ │ ├── source.md │ │ └── std-doc.md │ └── unsized │ │ ├── _index.md │ │ ├── source.md │ │ └── std-doc.md │ ├── result │ ├── _index.md │ └── result.md │ ├── std.md │ ├── sync │ ├── _index.md │ ├── arc.md │ ├── atomic-type.md │ ├── barrier.md │ ├── condvar.md │ ├── mpsc.md │ ├── mutex.md │ ├── once.md │ ├── rwlock.md │ └── sync.md │ └── thread │ ├── _index.md │ └── thread.md ├── docker-compose.yaml ├── docsy.work ├── docsy.work.sum ├── go.mod ├── go.sum ├── hugo.toml ├── layouts └── 404.html ├── package.json └── static ├── favicons ├── android-144x144.png ├── android-192x192.png ├── android-36x36.png ├── android-48x48.png ├── android-72x72.png ├── android-96x96.png ├── apple-touch-icon-180x180.png ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon-xxxx.ico ├── favicon.ico ├── pwa-192x192.png ├── pwa-512x512.png ├── tile150x150.png ├── tile310x150.png ├── tile310x310.png └── tile70x70.png ├── google5713250934492ab9.html └── images ├── favicon.ico └── logo.png /.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | !.gitignore 3 | public/ 4 | resources/ 5 | node_modules/ 6 | node_modules 7 | themes/ 8 | init_docsy.sh 9 | package-lock.json 10 | .hugo_build.lock 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution; 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. 24 | 25 | ## Community Guidelines 26 | 27 | This project follows 28 | [Google's Open Source Community Guidelines](https://opensource.google.com/conduct/). 29 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM floryn90/hugo:ext-alpine 2 | 3 | RUN apk add git && \ 4 | git config --global --add safe.directory /src 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rust学习笔记 2 | 3 | ### 内容介绍 4 | 5 | **Rust** 是一种安全、并发、实用的编程语言,有着惊人的运行速度,能够防止段错误,并保证线程安全, 能够构建可靠高效的软件。 6 | 7 | ### 访问方式 8 | 9 | 这是个人学习Rust的笔记,请点击下面的链接阅读: 10 | 11 | - [在线阅读](https://skyao.io/learning-rust/):hugo格式,界面清爽。托管于腾讯云香港节点,速度快,偶尔抽风 12 | - [@github](https://github.com/skyao/learning-rust/):源码托管于github,如有谬误或需讨论,请提issue,欢迎提交PR 13 | 14 | ### 版权申明 15 | 16 | 本笔记内容可以任意转载,但请注明来源并提供链接。 17 | 18 | -------------------------------------------------------------------------------- /assets/icons/Rust_programming_language_black_logo.svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/assets/icons/Rust_programming_language_black_logo.svg.png -------------------------------------------------------------------------------- /assets/icons/logo-xxxx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/assets/icons/logo-xxxx.png -------------------------------------------------------------------------------- /assets/icons/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/assets/icons/logo.png -------------------------------------------------------------------------------- /assets/icons/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | Rust programming language logoimage/svg+xml 3 | -------------------------------------------------------------------------------- /assets/scss/_variables_project.scss: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Add styles or override variables from the theme here. 4 | 5 | */ 6 | 7 | -------------------------------------------------------------------------------- /config.yaml: -------------------------------------------------------------------------------- 1 | # THIS IS A TEST CONFIG ONLY! 2 | # FOR THE CONFIGURATION OF YOUR SITE USE hugo.yaml. 3 | # 4 | # As of Docsy 0.7.0, Hugo 0.110.0 or later must be used. 5 | # 6 | # The sole purpose of this config file is to detect Hugo-module builds that use 7 | # an older version of Hugo. 8 | # 9 | # DO NOT add any config parameters to this file. You can safely delete this file 10 | # if your project is using the required Hugo version. 11 | 12 | module: 13 | hugoVersion: 14 | extended: true 15 | min: 0.110.0 16 | -------------------------------------------------------------------------------- /content/zh-cn/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Rust学习笔记 3 | --- 4 | 5 | {{< blocks/cover title="Rust学习笔记" image_anchor="top" height="full" >}} 6 | 7 | 阅读笔记内容 8 | 9 | 10 | 查看笔记源码 11 | 12 |

Learning is not compulsory… neither is survival.

13 | {{< blocks/link-down color="info" >}} 14 | {{< /blocks/cover >}} 15 | 16 | 17 | {{% blocks/lead color="primary" %}} 18 | Continual improvement allows people pride with increased productivity. But remember there is NO instant pudding. It is a long journey. Don’t tell me ten ways I can’t do something; tell me one way I can! It’s so easy to do nothing! It’s a challenge to do something. 19 | 20 | 持续改进让人们以提高生产力为荣。但请记住,没有什么是可以一蹴而就的。这是一个漫长的过程。不要告诉我不能做什么,告诉可以做什么! 什么都不做太容易了! 做一件事是一种挑战。 21 | 22 | Learning is not compulsory; it’s voluntary. Improvement is not compulsory; it’s voluntary. But to survive, we must learn. The penalty for ignorance is that you get beat up. There is no substitute for knowledge. Yet time is of the essence. 23 | 24 | 学习不是强制性的,而是自愿的。改进不是强制性的,是自愿的。但为了生存,我们必须学习。无知的惩罚是挨打。知识是无法替代的。时不我待,只争朝夕。 25 | 26 | —— by Jacob Walker 27 | {{% /blocks/lead %}} 28 | 29 | 30 | {{% blocks/section %}} 31 | Learning is not compulsory… neither is survival. 32 | {.h1 .text-center} 33 | {.h1 .text-center} 34 | {{% /blocks/section %}} 35 | 36 | 37 | {{% blocks/section %}} 38 | 当才能不足以撑起雄心壮志时,就应该静下心好好学习。 39 | {.h1 .text-center} 40 | {{% /blocks/section %}} -------------------------------------------------------------------------------- /content/zh-cn/books/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust书籍学习" 4 | linkTitle: "书籍" 5 | weight: 1 6 | date: 2021-11-29 7 | menu: 8 | main: 9 | weight: 40 10 | pre: 11 | cascade: 12 | type: "docs" 13 | --- 14 | 15 | {{% pageinfo %}} 16 | Rust书籍学习笔记 17 | {{% /pageinfo %}} 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /content/zh-cn/books/rust-atomics-and-locks/01-foreword/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "序言" 3 | linkTitle: "序言" 4 | weight: 100 5 | date: 2021-03-29 6 | description: > 7 | 低级并发实践 8 | --- 9 | 10 | 11 | 12 | 本书对Rust语言中的低级并发进行了很好的概述,包括线程、锁、引用计数、原子性、mailbox/channel 以及其他很多东西。它深入探讨了 CPU 和操作系统的问题,后者总结了使并发代码在 Linux、macOS 和 Windows 上正常工作的固有挑战。我特别高兴地看到,Mara 用 Rust 的工作代码来说明这些主题。书中最后讨论了信号灯、无锁链表、队列锁、序列锁,甚至是RCU。 13 | 14 | 那么,这本书能给像我这样的人带来什么呢?我已经写了近40年的C语言代码,最近一次是在Linux内核的深处。 15 | 16 | 我第一次了解 Rust 是在一些爱好者和Linux相关会议上。尽管如此,我还是很高兴地做着自己的事情,直到有人在一篇与Rust有关的LWN文章《使用Rust进行内核开发》中点名批评我。因此,我写了一个题为 "你想用Rust开发Linux内核?"的博客系列。这个博客系列引发了一些激烈的讨论,其中一些在该系列的评论中可以看到。 17 | 18 | 在其中一次讨论中,一位长期从事Linux内核开发,同时也写了很多Rust代码的人告诉我,在用Rust写并发代码时,你应该按照Rust希望你写的方式来写。我后来了解到,尽管这是一个很好的建议,但它留下了一个问题,即Rust到底想要什么。本书对这个问题给出了很好的答案,因此对希望学习并发的Rust开发者和希望学习如何在Rust中最好地编写并发代码的其他语言的开发者来说都很有价值。 19 | 20 | 我当然属于后者。然而,我必须承认,许多关于Rust并发性的激烈讨论让我想起了我的父母和祖父母在很久以前对锯子和钻头等电动工具上添加的不方便的安全功能的抱怨。其中一些安全功能现在已经无处不在,但锤子、凿子和电锯并没有什么变化。要研究出哪些机械安全功能能经受住时间的考验一点也不容易,所以我建议以一种极度谦逊的态度来对待软件安全功能。请理解,我是针对这些功能的支持者和反对者的。 21 | 22 | 这就把我们带到了另一个潜在的读者群体--Rust的怀疑者。虽然我相信大多数Rust怀疑论者通过指出改进的机会为社区提供了有价值的服务,但除了最精通Rust的怀疑论者之外,所有的人都会从阅读本书中受益。如果不出意外的话,这样做将使他们能够提供更尖锐和更有针对性的批评意见。 23 | 24 | 还有那些对Rust情有独钟的非Rust开发者,他们更愿意在自己喜欢的语言中实现Rust的并发相关安全机制。本书将让他们更深入地了解他们想要复制的Rust机制,或者更好的是,在此基础上进行改进。 25 | 26 | 最后,任何数量的Linux内核开发者都注意到了Rust在被纳入Linux内核方面所取得的进展;例如,见Jonathan Corbet的文章,"Rust在内核中的下一步"。截至2022年10月,这仍然是一个实验,但它被越来越认真地对待。事实上,认真到Linus Torvalds已经在Linux内核的6.1版本中接受了Rust语言支持的第一批内容。 27 | 28 | 无论你是为了扩大你的Rust剧目以包括并发,还是为了扩大你的并发剧目以包括Rust,还是为了改善你现有的非Rust环境,或者只是为了从不同的角度来看待并发,我都希望你在你的旅程中取得最好的成绩! 29 | 30 | Paul E. McKenney 31 | 32 | Meta Platforms 内核团队 33 | 34 | *Meta* 35 | 36 | 2022年10月 37 | -------------------------------------------------------------------------------- /content/zh-cn/books/rust-atomics-and-locks/02-preface/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "序言" 3 | linkTitle: "序言" 4 | weight: 100 5 | date: 2021-03-29 6 | description: > 7 | 序言 8 | --- 9 | 10 | 11 | 12 | Rust在使系统编程更容易理解方面已经发挥了,并且一直在发挥重要作用。然而,低层次的并发主题,如原子和内存排序,仍然经常被认为是有些神秘的主题,最好留给非常小的专家群体。 13 | 14 | 在过去的几年里,当我从事基于Rust的实时控制系统和Rust标准库的工作时,我发现许多关于原子学和相关主题的可用资源只涵盖了我所寻找的一小部分信息。许多资源完全集中在C和C++上,这就很难与Rust的(内存和线程)安全概念和类型系统形成联系。涵盖抽象理论细节的资源,如C++的内存模型,往往只能模糊地解释它与实际硬件的关系,如果有的话。有许多资源涵盖了实际硬件的每一个细节,如处理器指令和高速缓存一致性,但形成一个整体的理解往往需要从许多不同的地方收集零碎的信息。 15 | 16 | 本书试图把相关信息放在一个地方,把它们连接在一起,提供你所需要的一切,以建立你自己的正确、安全和符合人体工程学的并发原语,同时对底层硬件和操作系统的作用有足够的了解,以便能够做出设计决策和基本的优化权衡。 17 | -------------------------------------------------------------------------------- /content/zh-cn/books/rust-atomics-and-locks/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust Atomics and Locks" 3 | linkTitle: "Rust Atomics and Locks" 4 | weight: 100 5 | date: 2021-03-29 6 | description: > 7 | 低级并发实践 8 | --- 9 | 10 | 11 | 12 | ![cover](images/cover.png) 13 | 14 | https://learning.oreilly.com/library/view/rust-atomics-and/9781098119430/ 15 | -------------------------------------------------------------------------------- /content/zh-cn/books/rust-atomics-and-locks/images/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/content/zh-cn/books/rust-atomics-and-locks/images/cover.png -------------------------------------------------------------------------------- /content/zh-cn/core/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust核心库学习" 4 | linkTitle: "核心库" 5 | weight: 1 6 | date: 2021-11-29 7 | menu: 8 | main: 9 | weight: 30 10 | pre: 11 | cascade: 12 | type: "docs" 13 | --- 14 | 15 | {{% pageinfo %}} 16 | Rust核心库学习 17 | {{% /pageinfo %}} 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /content/zh-cn/core/ops/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "ops模块学习" 3 | linkTitle: "ops模块" 4 | weight: 10000 5 | date: 2021-11-29 6 | --- 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/zh-cn/core/ops/function/Fn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "trait core::ops::Fn" 3 | linkTitle: "Fn" 4 | weight: 10130 5 | date: 2021-11-29 6 | description: > 7 | Fn 由只对捕获的变量进行不可变引用或根本不捕获任何内容 8 | --- 9 | 10 | 11 | 12 | ## 源码 13 | 14 | Trait `core::ops::Fn` 的定义如下: 15 | 16 | ```rust 17 | pub trait Fn: FnMut { 18 | /// Performs the call operation. 19 | #[unstable(feature = "fn_traits", issue = "29625")] 20 | extern "rust-call" fn call(&self, args: Args) -> Self::Output; 21 | } 22 | ``` 23 | 24 | 25 | 26 | 27 | 28 | ## 官方文档 29 | 30 | https://doc.rust-lang.org/core/ops/trait.Fn.html 31 | 32 | 采用不可变接收者的调用运算符的版本。 33 | 34 | `Fn` 的实例可以在不改变状态的情况下重复调用。 35 | 36 | *请勿将此 trait (`Fn`) 与 [函数指针](https://doc.rust-lang.org/1.56.1/std/primitive.fn.html) (`fn`) 混淆。* 37 | 38 | `Fn` 由闭包自动实现,闭包只对捕获的变量进行不可变引用或根本不捕获任何内容,还有 (安全) [函数指针](https://doc.rust-lang.org/1.56.1/std/primitive.fn.html) (有一些警告,请参见其文档以获取更多详细信息)。 39 | 40 | 此外,对于实现 `Fn` 的任何类型 `F`,`&F` 也实现了 `Fn`。 41 | 42 | 由于 [`FnMut`](trait.FnMut.html) 和 [`FnOnce`](trait.FnOnce.html) 都是 `Fn` 的 supertraits,因此 `Fn` 的任何实例都可以用作参数,其中需要 [`FnMut`](trait.FnMut.html) 或 [`FnOnce`](trait.FnOnce.html)。 43 | 44 | 当您要接受类似函数类型的参数并且需要反复调用且不改变状态 (例如,同时调用它) 时,请使用 `Fn` 作为绑定。 如果不需要严格的要求,请使用 [`FnMut`](trait.FnMut.html) 或 [`FnOnce`](trait.FnOnce.html) 作为界限。 45 | 46 | 有关此主题的更多信息,请参见 [Rust 编程语言](../../book/ch13-01-closures.html) 中关于闭包的章节。 47 | 48 | 还要注意的是 `Fn` traits 的特殊语法 (例如 `Fn(usize, bool) -> usize`)。对此技术细节感兴趣的人可以参考 [Rustonomicon 中的相关部分](../../nomicon/hrtb.html)。 49 | 50 | ### 示例 51 | 52 | 调用一个闭包: 53 | 54 | ```rust 55 | let square = |x| x * x; 56 | assert_eq!(square(5), 25); 57 | ``` 58 | 59 | 使用 Fn 参数: 60 | 61 | ```rust 62 | fn call_with_one(func: F) -> usize 63 | where F: Fn(usize) -> usize { 64 | func(1) 65 | } 66 | 67 | let double = |x| x * 2; 68 | assert_eq!(call_with_one(double), 2); 69 | ``` 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /content/zh-cn/core/ops/function/FnMut.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "trait core::ops::FnMut" 3 | linkTitle: "FnMut" 4 | weight: 10120 5 | date: 2021-11-29 6 | description: > 7 | 想接受类似函数类型的参数并需要反复调用它,同时允许其改变状态时使用FnMut 8 | --- 9 | 10 | 11 | 12 | ## 源码 13 | 14 | Trait `core::ops::FnMut` 的定义如下: 15 | 16 | ```rust 17 | pub trait FnMut: FnOnce { 18 | /// Performs the call operation. 19 | #[unstable(feature = "fn_traits", issue = "29625")] 20 | extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; 21 | } 22 | ``` 23 | 24 | ## 官方文档 25 | 26 | https://doc.rust-lang.org/core/ops/trait.Fn.html 27 | 28 | 采用可变接收者的调用运算符的版本。 29 | 30 | `FnMut` 的实例可以重复调用,并且可以改变状态。 31 | 32 | `FnMut` 由闭包自动实现,闭包将可变引用引用到捕获的变量,以及实现 [`Fn`](trait.Fn.html) 的所有类型,例如 (safe) [函数指针](https://doc.rust-lang.org/1.56.1/std/primitive.fn.html) (因为 `FnMut` 是 [`Fn`](trait.Fn.html) 的特征)。 另外,对于任何实现 `FnMut` 的 `F` 类型,`&mut F` 也实现 `FnMut`。 33 | 34 | 由于 [`FnOnce`](trait.FnOnce.html) 是 `FnMut` 的 super trait,因此可以在期望 [`FnOnce`](trait.FnOnce.html) 的地方使用 `FnMut` 的任何实例,并且由于 [`Fn`](trait.Fn.html) 是 `FnMut` 的子特性,因此可以在预期 `FnMut` 的地方使用 [`Fn`](trait.Fn.html) 的任何实例。 35 | 36 | 当您想接受类似函数类型的参数并需要反复调用它,同时允许其改变状态时,请使用 `FnMut` 作为绑定。 如果您不希望参数改变状态,请使用 [`Fn`](trait.Fn.html) 作为绑定; 如果不需要重复调用,请使用 [`FnOnce`](trait.FnOnce.html)。 37 | 38 | 有关此主题的更多信息,请参见 [Rust 编程语言](../../book/ch13-01-closures.html) 中关于闭包的章节。 39 | 40 | 还要注意的是 `Fn` traits 的特殊语法 (例如 `Fn(usize, bool) -> usize`)。对此技术细节感兴趣的人可以参考 [Rustonomicon 中的相关部分](../../nomicon/hrtb.html)。 41 | 42 | ### 示例 43 | 44 | 调用可变捕获闭包 45 | 46 | ```rust 47 | let mut x = 5; 48 | { 49 | let mut square_x = || x *= x; 50 | square_x(); 51 | } 52 | assert_eq!(x, 25); 53 | ``` 54 | 55 | 使用 Fn 参数: 56 | 57 | ```rust 58 | fn call_with_one(func: F) -> usize 59 | where F: Fn(usize) -> usize { 60 | func(1) 61 | } 62 | 63 | let double = |x| x * 2; 64 | assert_eq!(call_with_one(double), 2); 65 | ``` 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /content/zh-cn/core/ops/function/FnOnce.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "trait core::ops::FnOnce" 3 | linkTitle: "FnOnce" 4 | weight: 10110 5 | date: 2021-11-29 6 | description: > 7 | Fn 接受类似函数类型的参数并且只需要调用一次 8 | --- 9 | 10 | 11 | 12 | ## 源码 13 | 14 | Trait `core::ops::FnOnce` 的定义如下: 15 | 16 | ```rust 17 | pub trait FnOnce { 18 | /// The returned type after the call operator is used. 19 | #[lang = "fn_once_output"] 20 | #[stable(feature = "fn_once_output", since = "1.12.0")] 21 | type Output; 22 | 23 | /// Performs the call operation. 24 | #[unstable(feature = "fn_traits", issue = "29625")] 25 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; 26 | } 27 | ``` 28 | 29 | 30 | 31 | ## 官方文档 32 | 33 | https://doc.rust-lang.org/core/ops/trait.FnOnce.html 34 | 35 | 具有按值接收者的调用运算符的版本。 36 | 37 | 可以调用 `FnOnce` 的实例,但可能无法多次调用。因此,如果唯一知道类型的是它实现 `FnOnce`,则只能调用一次。 38 | 39 | `FnOnce` 由可能消耗捕获变量的闭包以及实现 [`FnMut`](trait.FnMut.html) 的所有类型 (例如 (safe) [函数指针](https://doc.rust-lang.org/1.56.1/std/primitive.fn.html) (因为 `FnOnce` 是 [`FnMut`](trait.FnMut.html) 的特征) ) 自动实现。 40 | 41 | 由于 [`Fn`](trait.Fn.html) 和 [`FnMut`](trait.FnMut.html) 都是 `FnOnce` 的子特性,因此可以在期望使用 `FnOnce` 的情况下使用 [`Fn`](trait.Fn.html) 或 [`FnMut`](trait.FnMut.html) 的任何实例。 42 | 43 | 当您想接受类似函数类型的参数并且只需要调用一次时,可以使用 `FnOnce` 作为绑定。 如果需要重复调用该参数,请使用 [`FnMut`](trait.FnMut.html) 作为界限; 如果还需要它不改变状态,请使用 [`Fn`](trait.Fn.html)。 44 | 45 | 有关此主题的更多信息,请参见 [Rust 编程语言](../../book/ch13-01-closures.html) 中关于闭包的章节。 46 | 47 | 还要注意的是 `Fn` traits 的特殊语法 (例如 `Fn(usize, bool) -> usize`)。对此技术细节感兴趣的人可以参考 [Rustonomicon 中的相关部分](../../nomicon/hrtb.html)。 48 | 49 | ### 示例 50 | 51 | 使用 FnOnce 参数: 52 | 53 | ```rust 54 | fn consume_with_relish(func: F) 55 | where F: FnOnce() -> String 56 | { 57 | // `func` 使用其捕获的变量,因此不能多次运行。 58 | println!("Consumed: {}", func()); 59 | 60 | println!("Delicious!"); 61 | 62 | // 再次尝试调用 `func()` 将为 `func` 引发 `use of moved value` 错误。 63 | } 64 | 65 | let x = String::from("x"); 66 | let consume_and_return_x = move || x; 67 | consume_with_relish(consume_and_return_x); 68 | 69 | // `consume_and_return_x` 现在不能再被调用 70 | ``` 71 | 72 | -------------------------------------------------------------------------------- /content/zh-cn/core/ops/function/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "ops function" 3 | linkTitle: "function" 4 | weight: 10100 5 | date: 2021-11-29 6 | description: > 7 | Fn,FnMut和FnOnce 8 | --- 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /content/zh-cn/core/ops/ops-module.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "ops模块概述" 3 | linkTitle: "概述" 4 | weight: 10001 5 | date: 2021-11-29 6 | description: > 7 | 可重载的算符 8 | --- 9 | 10 | 11 | 12 | ops = Overloadable operators = 可重载的运算符 13 | 14 | 15 | 16 | ## 官方文档 17 | 18 | https://doc.rust-lang.org/core/ops/ 19 | 20 | 可重载的运算符。 21 | 22 | 实现这些 traits 可使您重载某些运算符。 23 | 24 | 其中的某些 traits 由 prelude 导入,因此在每个 Rust 程序中都可用。只能重载由 traits 支持的运算符。 例如,可以通过 [`Add`](trait.Add.html) trait 重载加法运算符 (`+`),但是由于赋值运算符 (`=`) 没有后备 trait,因此无法重载其语义。 此外,此模块不提供任何机制来创建新的运算符。 如果需要无特征重载或自定义运算符,则应使用宏或编译器插件来扩展 Rust 的语法。 25 | 26 | 考虑到它们的通常含义和 [运算符优先级](../../reference/expressions.html#expression-precedence),运算符 traits 的实现在它们各自的上下文中应该不足为奇。 例如,当实现 [`Mul`](trait.Mul.html) 时,该操作应与乘法有些相似 (并共享期望的属性,如关联性)。 27 | 28 | 请注意,`&&` 和 `||` 运算符发生短路,即,它们仅在第二操作数对结果有贡献的情况下才对其求值。由于 traits 无法强制执行此行为,因此不支持 `&&` 和 `||` 作为可重载的运算符。 29 | 30 | 许多运算符都按值取其操作数。在涉及内置类型的非泛型上下文中,这通常不是问题。 但是,如果必须重用值而不是让运算符使用它们,那么在泛型代码中使用这些运算符就需要引起注意。一种选择是偶尔使用 [`clone`](../clone/trait.Clone.html#tymethod.clone)。 另一个选择是依靠所涉及的类型,为引用提供其他运算符实现。 例如,对于应该支持加法的用户定义类型 `T`,将 `T` 和 `&T` 都实现 traits [`Add`](trait.Add.html) 和 [`Add<&T>`](trait.Add.html) 可能是一个好主意,这样就可以编写泛型代码而不必进行不必要的克隆。 31 | 32 | ### 示例 33 | 34 | 本示例创建一个实现 [`Add`](trait.Add.html) 和 [`Sub`](trait.Sub.html) 的 `Point` 结构体,然后演示加减两个 Point。 35 | 36 | ```rust 37 | use std::ops::{Add, Sub}; 38 | 39 | #[derive(Debug, Copy, Clone, PartialEq)] 40 | struct Point { 41 | x: i32, 42 | y: i32, 43 | } 44 | 45 | impl Add for Point { 46 | type Output = Self; 47 | 48 | fn add(self, other: Self) -> Self { 49 | Self {x: self.x + other.x, y: self.y + other.y} 50 | } 51 | } 52 | 53 | impl Sub for Point { 54 | type Output = Self; 55 | 56 | fn sub(self, other: Self) -> Self { 57 | Self {x: self.x - other.x, y: self.y - other.y} 58 | } 59 | } 60 | ``` 61 | 62 | 有关示例实现,请参见每个 trait 的文档。 63 | 64 | [`Fn`](trait.Fn.html),[`FnMut`](trait.FnMut.html) 和 [`FnOnce`](trait.FnOnce.html) traits 由可以像函数一样调用的类型实现。请注意,[`Fn`](trait.Fn.html) 占用 `&self`,[`FnMut`](trait.FnMut.html) 占用 `&mut self`,[`FnOnce`](trait.FnOnce.html) 占用 `self`。 这些对应于可以在实例上调用的三种方法:引用调用、可变引用调用和值调用。 这些 traits 的最常见用法是充当以函数或闭包为参数的高级函数的界限。 65 | 66 | 以 [`Fn`](trait.Fn.html) 作为参数: 67 | 68 | ```rust 69 | fn call_with_one(func: F) -> usize 70 | where F: Fn(usize) -> usize 71 | { 72 | func(1) 73 | } 74 | 75 | let double = |x| x * 2; 76 | assert_eq!(call_with_one(double), 2); 77 | ``` 78 | 79 | 以 [`FnMut`](trait.FnMut.html) 作为参数: 80 | 81 | ```rust 82 | fn do_twice(mut func: F) 83 | where F: FnMut() 84 | { 85 | func(); 86 | func(); 87 | } 88 | 89 | let mut x: usize = 1; 90 | { 91 | let add_two_to_x = || x += 2; 92 | do_twice(add_two_to_x); 93 | } 94 | 95 | assert_eq!(x, 5); 96 | ``` 97 | 98 | 以 [`FnOnce`](trait.FnOnce.html) 作为参数: 99 | 100 | ```rust 101 | fn consume_with_relish(func: F) 102 | where F: FnOnce() -> String 103 | { 104 | // `func` 使用其捕获的变量,因此不能多次运行 105 | // 106 | println!("Consumed: {}", func()); 107 | 108 | println!("Delicious!"); 109 | 110 | // 再次尝试调用 `func()` 将为 `func` 引发 `use of moved value` 错误 111 | // 112 | } 113 | 114 | let x = String::from("x"); 115 | let consume_and_return_x = move || x; 116 | consume_with_relish(consume_and_return_x); 117 | 118 | // `consume_and_return_x` 现在不能再被调用 119 | ``` 120 | 121 | -------------------------------------------------------------------------------- /content/zh-cn/docs/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust学习笔记" 3 | linkTitle: "学习笔记" 4 | weight: 1 5 | date: 2021-03-29 6 | menu: 7 | main: 8 | weight: 20 9 | pre: 10 | date: 2021-08-18 11 | description: > 12 | Rust 学习笔记 13 | --- 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /content/zh-cn/docs/build/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust构建" 3 | linkTitle: "构建" 4 | weight: 1000 5 | date: 2021-03-29 6 | description: > 7 | Rust 构建 8 | --- 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/zh-cn/docs/build/cargo/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust Cargo" 3 | linkTitle: "Cargo" 4 | weight: 320 5 | date: 2021-03-29 6 | description: > 7 | Rust Cargo 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /content/zh-cn/docs/build/cargo/cargo-book/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust Cargo Book笔记" 3 | linkTitle: "Cargo Book" 4 | weight: 325 5 | date: 2021-10-21 6 | description: > 7 | Rust Cargo Book笔记 8 | --- 9 | 10 | https://doc.rust-lang.org/cargo/index.html 11 | -------------------------------------------------------------------------------- /content/zh-cn/docs/build/cargo/cargo-book/reference-workspaces.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Cargo Reference笔记: 工作区" 3 | linkTitle: "Reference 3.3工作区" 4 | weight: 328 5 | date: 2021-10-22 6 | description: > 7 | Rust Cargo Reference笔记:3.3节工作区 8 | --- 9 | 10 | https://doc.rust-lang.org/cargo/reference/workspaces.html 11 | 12 | ## 3.3 工作区 13 | 14 | 工作空间是一个或多个软件包的集合,它们共享共同的依赖性解析(有一个共享的Cargo.lock)、输出目录和各种设置,如配置文件。作为工作区一部分的包被称为工作区成员。有两种类型的工作空间:根包(Root package)或虚拟清单(Virtual manifest)。 15 | 16 | ### 根包(Root Package) 17 | 18 | 通过在 `Cargo.toml` 中添加 `[workspace]` 部分可以创建一个工作区。这可以添加到已经定义了 `[package]` 的 `Cargo.toml` 中,在这种情况下,该包是工作区的根包(Root package)。工作区根(workspace root)是工作区的 `Cargo.toml` 所在的目录。 19 | 20 | ### 虚拟清单(Virtual Manifest) 21 | 22 | 另外,在创建 Cargo.toml 文件时,也可以在其中加入 `[workspace]` 部分,但不加入 `[package]` 部分。这被称为虚拟清单。这通常适用于没有 "主要 " 软件包的情况,或者您希望将所有软件包放在不同的目录中。 23 | 24 | ### 关键特征 25 | 26 | 工作区的关键点是: 27 | 28 | - 所有软件包共享一个共同的 `Cargo.lock` 文件,该文件驻留在工作区根部。 29 | 30 | - 所有软件包共享一个共同的输出目录,该目录默认为工作区根目录下的target。 31 | 32 | - `Cargo.toml` 中的 `[patch]`、`[replace]` 和 `[profile.*]` 部分只在根清单中被识别,而在 crate 的清单中被忽略。 33 | 34 | ### [workspace]部分 35 | 36 | `Cargo.toml` 中的 `[workspace]` 表定义了哪些软件包是工作区的成员。 37 | 38 | ```toml 39 | [workspace] 40 | members = ["member1", "path/to/member2", "crates/*"] 41 | exclude = ["crates/foo", "path/to/other"] 42 | ``` 43 | 44 | 驻留在工作区目录中的所有路径依赖自动成为成员。其他成员可以用 members 键列出,members 键应该是一个包含 `Cargo.toml` 文件的目录的字符串数组。 45 | 46 | 成员列表还支持使用典型的文件名glob模式,如 `*` 和 `?` 47 | 48 | exclude key 可以用来防止路径被包含在一个工作区中。如果某些路径的依赖关系根本不希望出现在工作区中,或者使用 glob 模式而你想删除一个目录,这就很有用。 49 | 50 | 空的 `[workspace]` 表可以和 `[package]` 一起使用,以方便地创建一个包含该包和其所有路径依赖的工作区。 51 | 52 | ### 工作区选择 53 | 54 | 当在工作区的子目录内时,`Cargo` 会自动在父目录中搜索带有 `[workspace]` 定义的 `Cargo.toml` 文件,以确定使用哪个工作区。`package.workspace` 清单键可以在 crate 中用来指向工作空间的根,以覆盖这种自动搜索。如果成员不在工作区根的子目录内,手动设置会很有用。 55 | 56 | ### 包的选择 57 | 58 | 在工作区中,与包相关的 `cargo` 命令,如 `cargo build`,可以使用 `-p / --package` 或 `--workspace` 命令行标志来决定对哪些包进行操作。如果没有指定这两个标志,Cargo将使用当前工作目录下的软件包。如果当前目录是一个虚拟工作区,它将适用于所有成员(就像在命令行中指定 `--workspace` 一样)。 59 | 60 | 可以指定可选的 `default-members` 键,以设置在工作区根部和不使用包选择标志时要操作的成员。 61 | 62 | ```toml 63 | [workspace] 64 | members = ["path/to/member1", "path/to/member2", "path/to/member3/*"] 65 | default-members = ["path/to/member2", "path/to/member3/foo"] 66 | ``` 67 | 68 | 当指定时,`default-members` 必须扩展到一个成员的子集。 69 | 70 | ### Workspace.metadata表 71 | 72 | `Workspace.metadata` 表会被 `Cargo` 忽略,不会被警告。这一部分可以用于那些想在 `Cargo.toml` 中存储工作空间配置的工具。比如说。 73 | 74 | ```toml 75 | [workspace] 76 | members = ["member1", "member2"] 77 | 78 | [workspace.metadata.webcontents] 79 | root = "path/to/webproject" 80 | tool = ["npm", "run", "build"] 81 | # ... 82 | ``` 83 | 84 | 在 `package.metadata` 中也有一组类似的表格。虽然 cargo 没有为这两个表的内容指定格式,但建议外部工具可能希望以一致的方式使用它们,例如,如果 `package.metadata` 中缺少数据,可以参考 `workspace.metadata` 中的数据,如果这对相关工具来说是有意义的。 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /content/zh-cn/docs/build/cargo/cargo.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Cargo概述" 3 | linkTitle: "概述" 4 | date: 2021-10-21 5 | weight: 321 6 | description: > 7 | Cargo概述 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /content/zh-cn/docs/build/cargo/settings.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Cargo设置" 3 | linkTitle: "Cargo设置" 4 | date: 2021-07-05 5 | weight: 322 6 | description: > 7 | Cargo设置: Cargo Crates Registry Source设置和代理设置 8 | --- 9 | 10 | ## source设置 11 | 12 | Cargo Crates Registry Source设置. 13 | 14 | ### 添加source 15 | 16 | 为了加快 cargo 的下载速度,避免网速慢或者被墙,添加国内源头 ustc ,需修改 `~/.cargo/config` 加入以下内容: 17 | 18 | ```properties 19 | [source.crates-io] 20 | registry = "https://github.com/rust-lang/crates.io-index" 21 | replace-with = 'ustc' 22 | 23 | [source.ustc] 24 | registry = "git://mirrors.ustc.edu.cn/crates.io-index" 25 | #registry = "https://mirrors.ustc.edu.cn/crates.io-index" 26 | 27 | [http] 28 | check-revoke = false 29 | ``` 30 | 31 | 其中添加 `check-revoke = false` 是为了解决下面的问题: 32 | 33 | ``` 34 | warning: spurious network error (2 tries remaining): [6] Couldn't resolve host name (Could not resolve host: crates-io.proxy.ustclug.org) 35 | warning: spurious network error (1 tries remaining): [6] Couldn't resolve host name (Could not resolve host: crates-io.proxy.ustclug.org) 36 | error: failed to download from `https://crates-io.proxy.ustclug.org/api/v1/crates/serde_test/1.0.126/download` 37 | 38 | Caused by: 39 | [6] Couldn't resolve host name (Could not resolve host: crates-io.proxy.ustclug.org) 40 | 41 | ``` 42 | 43 | 44 | 45 | ### 参考资料 46 | 47 | - [Rust Crates 源使用帮助 — USTC Mirror Help 文档](http://mirrors.ustc.edu.cn/help/crates.io-index.html) 48 | 49 | ## 代理设置 50 | 51 | ### 网络代理问题 52 | 53 | 执行 make 命令时遇到问题,卡在 git clone 上: 54 | 55 | ```bash 56 | $ make 57 | cargo fetch --locked 58 | Updating git repository `https://github.com/linkerd/prost` 59 | ......(速度太慢,卡住过不去) 60 | ``` 61 | 62 | ### git代理设置 63 | 64 | 我平时一般用 ssh 方式操作git,通过设置 `~/.ssh/config` 文件的方式来设置代理,如: 65 | 66 | ```bash 67 | # 这里必须是 github.com,因为这个跟我们 clone 代码时的链接有关 68 | Host github.com 69 | # 如果用默认端口,这里是 github.com,如果想用443端口,这里就是 ssh.github.com 详 70 | 见 https://help.github.com/articles/using-ssh-over-the-https-port/ 71 | #HostName ssh.github.com 72 | HostName github.com 73 | User git 74 | # 如果是 HTTP 代理,把下面这行取消注释,并把 proxyport 改成自己的 http 代理的端>口 75 | #ProxyCommand socat - PROXY:127.0.0.1:%h:%p,proxyport=3333 76 | 77 | # 如果是 socks5 代理,则把下面这行取消注释,并把 23456 改成自己 socks5 代理的端口 78 | ProxyCommand nc -v -x 127.0.0.1:23456 %h %p 79 | ``` 80 | 81 | 上面信息中时通过 https 来操作git仓库,所以想着设置 git 的 http 代理,常见的方式是通过 `git config --global` 命令,支持 http 代理和 socks5 代理: 82 | 83 | ```bash 84 | # 使用 http 代理 85 | git config --global http.proxy http://192.168.0.1:3333 86 | 87 | # 使用 socks5 代理 88 | git config --global http.proxy socks5://192.168.0.1:23456 89 | ``` 90 | 91 | 可以在 `~/.gitconfig` 中看到设置的结果。 92 | 93 | - 参考:[Configure Git to use a proxy](https://gist.github.com/evantoli/f8c23a37eb3558ab8765) 94 | 95 | ### Cargo代理设置 96 | 97 | 但是,上面的设置只对直接使用 git 命令有效,当使用 cargo 命令时,依然会卡住。 98 | 99 | 需要为 cargo 单独设置代理,新建或打开文件 `~/.cargo/config` ,使用 http 代理: 100 | 101 | ```bash 102 | [http] 103 | proxy = "192.168.0.1:3333" 104 | [https] 105 | proxy = "192.168.0.1:3333" 106 | ``` 107 | 108 | 使用 socks5代理: 109 | 110 | ```bash 111 | [http] 112 | proxy = "socks5://192.168.0.1:23456" 113 | [https] 114 | proxy = "socks5://192.168.0.1:23456" 115 | ``` 116 | 117 | -------------------------------------------------------------------------------- /content/zh-cn/docs/build/lints/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust Lints" 3 | linkTitle: "Lints" 4 | weight: 340 5 | date: 2021-03-29 6 | description: > 7 | Rust Lints 8 | --- 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/zh-cn/docs/build/lints/deny-by-default.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "默认为Deny的Lints" 3 | linkTitle: "默认为Deny" 4 | date: 2021-03-29 5 | weight: 346 6 | description: > 7 | Rustc 默认为Deny的Lints 8 | --- 9 | 10 | > 英文原文地址: https://doc.rust-lang.org/rustc/lints/listing/deny-by-default.html 11 | 12 | 默认情况下,这些 lint 都设置为’deny’级别。 13 | 14 | ### exceeding-bitshifts 15 | 16 | 此 lint 检测到移位超出了类型的位数。一些触发此 lint 的示例代码: 17 | 18 | ```rust 19 | 1_i32 << 32; 20 | ``` 21 | 22 | 这将产生: 23 | 24 | ```text 25 | error: bitshift exceeds the type's number of bits 26 | --> src/main.rs:2:5 27 | | 28 | 2 | 1_i32 << 32; 29 | | ^^^^^^^^^^^ 30 | | 31 | ``` 32 | 33 | ### invalid-type-param-default 34 | 35 | 此 lint 检测在无效位置中,允许的类型参数默认值错误。一些触发此 lint 的示例代码: 36 | 37 | ```rust 38 | fn foo(t: T) {} 39 | ``` 40 | 41 | 这将产生: 42 | 43 | ```text 44 | error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions. 45 | --> src/main.rs:4:8 46 | | 47 | 4 | fn foo(t: T) {} 48 | | ^ 49 | | 50 | = note: #[deny(invalid_type_param_default)] on by default 51 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! 52 | = note: for more information, see issue #36887 53 | ``` 54 | 55 | ### legacy-constructor-visibility 56 | 57 | [RFC 1506](https://github.com/rust-lang/rfcs/blob/master/text/1506-adt-kinds.md)修改了一些可见性规则,并改变了 struct 构造函数的可见性。一些触发此 lint 的示例代码: 58 | 59 | ```rust 60 | mod m { 61 | pub struct S(u8); 62 | 63 | fn f() { 64 | // this is trying to use S from the 'use' line, but because the `u8` is 65 | // not pub, it is private 66 | ::S; 67 | } 68 | } 69 | 70 | use m::S; 71 | ``` 72 | 73 | 这将产生: 74 | 75 | ```text 76 | error: private struct constructors are not usable through re-exports in outer modules 77 | --> src/main.rs:5:9 78 | | 79 | 5 | ::S; 80 | | ^^^ 81 | | 82 | = note: #[deny(legacy_constructor_visibility)] on by default 83 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! 84 | = note: for more information, see issue #39207 85 | ``` 86 | 87 | ### legacy-directory-ownership 88 | 89 | 发出 `legacy_directory_ownership` 时发出 90 | 91 | - 有一个带有`#[path]`属性的非内联模块(例如`#[path = "foo.rs"]`mod bar;), 92 | - 模块的文件(上例中的“foo.rs”)是未命名为“mod.rs”,并且 93 | - 模块的文件包含一个`#[path]`属性的非内联模块。 94 | 95 | 可以通过将父模块重命名为“mod.rs”,并将其移动到其自己的目录(如果合适的话)来修复警告。 96 | 97 | [missing-fragment-specifier](http://llever.com/rustc-zh/lints/listing/deny-by-default.zh.html#missing-fragment-specifier) 98 | 99 | 当一个未使用的`macro_rules!`宏定义模式出现时,会发出 missing_fragment_specifier 警告,因其有一个元变量(例如`$e`)后面没有片段说明符(例如`:expr`)。 100 | 101 | 通过删除未使用的`macro_rules!`宏定义模式,可以始终修复此警告。 102 | 103 | ### mutable-transmutes 104 | 105 | 这种 lint 抓取`&T`到`&mut T`的转化,因为它是未定义的行为。一些触发此 lint 的示例代码: 106 | 107 | ```rust 108 | unsafe { 109 | let y = std::mem::transmute::<&i32, &mut i32>(&5); 110 | } 111 | ``` 112 | 113 | 这将产生: 114 | 115 | ```text 116 | error: mutating transmuted &mut T from &T may cause undefined behavior, consider instead using an UnsafeCell 117 | --> src/main.rs:3:17 118 | | 119 | 3 | let y = std::mem::transmute::<&i32, &mut i32>(&5); 120 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 121 | | 122 | ``` 123 | 124 | ### no-mangle-const-items 125 | 126 | 这个 lint 检测到任何带`#[no_mangle]`属性的`const`项。常量确实没有导出符号,因此,这可能意味着您打算使用`static`不是`const`。一些触发此 lint 的示例代码: 127 | 128 | ```rust 129 | #[no_mangle] 130 | const FOO: i32 = 5; 131 | ``` 132 | 133 | 这将产生: 134 | 135 | ```text 136 | error: const items should never be #[no_mangle] 137 | --> src/main.rs:3:1 138 | | 139 | 3 | const FOO: i32 = 5; 140 | | -----^^^^^^^^^^^^^^ 141 | | | 142 | | help: try a static value: `pub static` 143 | | 144 | ``` 145 | 146 | ### overflowing-literals 147 | 148 | 此 lint 检测其类型的字面值超出范围。一些触发此 lint 的示例代码: 149 | 150 | ```rust 151 | let x: u8 = 1000; 152 | ``` 153 | 154 | 这将产生: 155 | 156 | ```text 157 | error: literal out of range for u8 158 | --> src/main.rs:2:17 159 | | 160 | 2 | let x: u8 = 1000; 161 | | ^^^^ 162 | | 163 | ``` 164 | 165 | ### parenthesized-params-in-types-and-modules 166 | 167 | 此 lint 检测到不正确的括号。一些触发此 lint 的示例代码: 168 | 169 | ```rust 170 | let x = 5 as usize(); 171 | ``` 172 | 173 | 这将产生: 174 | 175 | ```text 176 | error: parenthesized parameters may only be used with a trait 177 | --> src/main.rs:2:21 178 | | 179 | 2 | let x = 5 as usize(); 180 | | ^^ 181 | | 182 | = note: #[deny(parenthesized_params_in_types_and_modules)] on by default 183 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! 184 | = note: for more information, see issue #42238 185 | ``` 186 | 187 | 要修复它,请删除多个`()`。 188 | 189 | ### pub-use-of-private-extern-crate 190 | 191 | 此 lint 检测重新导出一个私有`extern crate`的特定情况; 192 | 193 | [safe-extern-statics](http://llever.com/rustc-zh/lints/listing/deny-by-default.zh.html#safe-extern-statics) 194 | 195 | 在旧版本的 Rust 中,允许`extern static`以安全代码访问,会存在安全问题。这个 lint 现在抓住并否认这种代码。 196 | 197 | [unknown-crate-types](http://llever.com/rustc-zh/lints/listing/deny-by-default.zh.html#unknown-crate-types) 198 | 199 | 此 lint 检测到在一个`#[crate_type]`指示中,发现一个未知箱类型。一些触发此 lint 的示例代码: 200 | 201 | ```rust 202 | #![crate_type="lol"] 203 | ``` 204 | 205 | 这将产生: 206 | 207 | ```text 208 | error: invalid `crate_type` value 209 | --> src/lib.rs:1:1 210 | | 211 | 1 | #![crate_type="lol"] 212 | | ^^^^^^^^^^^^^^^^^^^^ 213 | | 214 | ``` 215 | 216 | ### incoherent-fundamental-impls 217 | 218 | 此 lint 检测到错误允许的潜在冲突的 impl。一些触发此 lint 的示例代码: 219 | 220 | ```rust 221 | pub trait Trait1 { 222 | type Output; 223 | } 224 | 225 | pub trait Trait2 {} 226 | 227 | pub struct A; 228 | 229 | impl Trait1 for T where T: Trait2 { 230 | type Output = (); 231 | } 232 | 233 | impl Trait1> for A { 234 | type Output = i32; 235 | } 236 | ``` 237 | 238 | 这将产生: 239 | 240 | ```text 241 | error: conflicting implementations of trait `Trait1>` for type `A`: (E0119) 242 | --> src/main.rs:13:1 243 | | 244 | 9 | impl Trait1 for T where T: Trait2 { 245 | | --------------------------------------------- first implementation here 246 | ... 247 | 13 | impl Trait1> for A { 248 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `A` 249 | | 250 | = note: #[deny(incoherent_fundamental_impls)] on by default 251 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! 252 | = note: for more information, see issue #46205 253 | 254 | ``` -------------------------------------------------------------------------------- /content/zh-cn/docs/build/lints/groups.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lints分组" 3 | linkTitle: "Lints分组" 4 | date: 2021-03-29 5 | weight: 343 6 | description: > 7 | Rustc的Lints分组 8 | --- 9 | 10 | > 备注:翻译自英文原文: https://doc.rust-lang.org/rustc/lints/groups.html 11 | 12 | `rustc` 具有“Lint Group”的概念,您可以通过一个名称切换多个警告。 13 | 14 | 例如,`nonstandard-style` lint 一次性设置 `non-camel-case-types`, `non-snake-case`以及`non-upper-case-globals`。所以一下是等效的: 15 | 16 | ```bash 17 | $ rustc -D nonstandard-style 18 | $ rustc -D non-camel-case-types -D non-snake-case -D non-upper-case-globals 19 | ``` 20 | 21 | 以下是每个Lint组及其组成的Lint的列表: 22 | 23 | | 组 | 描述 | 棉绒 | 24 | | ------------------- | ---------------------------------- | ------------------------------------------------------------ | 25 | | nonstandard-style | 违反标准命名约定 | 非驼峰式,非蛇形,非大写全局
non-camel-case-types, non-snake-case, non-upper-case-globals | 26 | | warnings | 发出警告的所有Lint | 发出警告的所有Lint | 27 | | 2018版 | 在Rust 2018中将变成错误的Lint | tyvar-behind-raw-pointer | 28 | | rust-2018-idioms | 推动您朝Rust 2018的惯例前进的Lint | bare-trait-object, unreachable-pub | 29 | | unused | 检测到已声明但未使用的事物的Lint | unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-allocation, unused-doc-comment, unused-extern-crates, unused-features, unused-parens | 30 | | future-incompatible | 检测到代码具有未来兼容性问题的Lint | private-in-public, pub-use-of-private-extern-crate, patterns-in-fns-without-body, safe-extern-statics, invalid-type-param-default, legacy-directory-ownership, legacy-imports, legacy-constructor-visibility, missing-fragment-specifier, illegal-floating-point-literal-pattern, anonymous-parameters, parenthesized-params-in-types-and-modules, late-bound-lifetime-arguments, safe-packed-borrows, tyvar-behind-raw-pointer, unstable-name-collision | 31 | 32 | 此外,还有一个`bad-style` Lint Group,它是 `nonstandard-style` 的别名,但已经不推荐使用。 33 | 34 | 最后,您还可以通过调用来查看上表`rustc -W help`。这将为您已安装的特定编译器提供确切值。 -------------------------------------------------------------------------------- /content/zh-cn/docs/build/lints/levels.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lints等级" 3 | linkTitle: "Lints等级" 4 | date: 2021-03-29 5 | weight: 342 6 | description: > 7 | Rustc的Lints等级 8 | --- 9 | 10 | > 英文原文地址: https://doc.rust-lang.org/rustc/lints/levels.html 11 | 12 | 在 `rustc` 中,Lints分为四个*级别*: 13 | 14 | 1. 允许/allow 15 | 2. 警告/warn 16 | 3. 拒绝/deny 17 | 4. 禁止/forbid 18 | 19 | 每个Lint都有一个默认级别(在本章后面的Lint列表中有解释),编译器有一个默认警告级别。首先,让我们解释这些级别的含义,然后再讨论配置。 20 | 21 | ### 允许/allow 22 | 23 | 这些Lints存在,但默认情况下不执行任何操作。例如,考虑以下源代码: 24 | 25 | ```rust 26 | pub fn foo() {} 27 | ``` 28 | 29 | 编译此文件不会产生警告: 30 | 31 | ```bash 32 | $ rustc lib.rs --crate-type=lib 33 | $ 34 | ``` 35 | 36 | 但是此代码违反了`missing_docs` lints。 37 | 38 | 这些Lint主要是通过配置手动打开的,我们将在本节后面讨论。 39 | 40 | ### 警告/warn 41 | 42 | 如果违反lint,“警告/warn” Lints等级将产生警告。例如,此代码违反了`unused_variable` lint: 43 | 44 | ```rust 45 | pub fn foo() { 46 | let x = 5; 47 | } 48 | ``` 49 | 50 | 这将产生以下警告: 51 | 52 | ```bash 53 | $ rustc lib.rs --crate-type=lib 54 | warning: unused variable: `x` 55 | --> lib.rs:2:9 56 | | 57 | 2 | let x = 5; 58 | | ^ 59 | | 60 | = note: `#[warn(unused_variables)]` on by default 61 | = note: to avoid this warning, consider using `_x` instead 62 | ``` 63 | 64 | ### 拒绝/deny 65 | 66 | 如果违反,“拒绝” lint 将产生错误。例如,此代码导致了 `exceeding_bitshifts` lint。 67 | 68 | ```rust 69 | fn main() { 70 | 100u8 << 10; 71 | } 72 | $ rustc main.rs 73 | error: bitshift exceeds the type's number of bits 74 | --> main.rs:2:13 75 | | 76 | 2 | 100u8 << 10; 77 | | ^^^^^^^^^^^ 78 | | 79 | = note: `#[deny(exceeding_bitshifts)]` on by default 80 | ``` 81 | 82 | Lint错误和常规的旧错误有什么区别?Lint可通过级别进行配置,因此,与“允许/allow” Lint相似,默认情况下设置为“拒绝/deny”,则警告/warn 让您允许它们。同样,您可能希望设置一个Lints,`warn` 默认情况下会产生错误。此Lint等级可为您提供。 83 | 84 | ### 禁止/forbid 85 | 86 | “禁止/forbid”是一种特殊的Lint级别,比“拒绝/deny”级别高。与“拒绝/deny”相同的是,在此级别的Lint将产生错误,但是与“拒绝/deny”级别不同,“禁止/forbid”级别不能被覆盖为低于错误的任何值。但是,Lint的水平可能仍会受到限制`--cap-lints` (请参见下文),因此`rustc --cap-lints warn`将使Lint设置为“禁止/forbid”只是警告。 87 | 88 | ### 配置警告级别 89 | 90 | 还记得我们`missing_docs`从“允许/allow”Lint级别开始的示例吗? 91 | 92 | ```bash 93 | $ cat lib.rs 94 | pub fn foo() {} 95 | $ rustc lib.rs --crate-type=lib 96 | $ 97 | ``` 98 | 99 | 我们可以使用编译器标志以及源代码中的属性来配置该Lint以更高级别运行。 100 | 101 | 您还可以“限制”Lint,以便编译器可以选择忽略某些Lint级别。我们将在最后讨论。 102 | 103 | #### 通过编译器标志 104 | 105 | 在`-A`,`-W`,`-D`,和`-F`标志让你把一个或多个Lint设置成允许,警告,拒绝或禁止的等级,就像这样: 106 | 107 | ```bash 108 | $ rustc lib.rs --crate-type=lib -W missing-docs 109 | warning: missing documentation for crate 110 | --> lib.rs:1:1 111 | | 112 | 1 | pub fn foo() {} 113 | | ^^^^^^^^^^^^ 114 | | 115 | = note: requested on the command line with `-W missing-docs` 116 | 117 | warning: missing documentation for a function 118 | --> lib.rs:1:1 119 | | 120 | 1 | pub fn foo() {} 121 | | ^^^^^^^^^^^^ 122 | $ rustc lib.rs --crate-type=lib -D missing-docs 123 | error: missing documentation for crate 124 | --> lib.rs:1:1 125 | | 126 | 1 | pub fn foo() {} 127 | | ^^^^^^^^^^^^ 128 | | 129 | = note: requested on the command line with `-D missing-docs` 130 | 131 | error: missing documentation for a function 132 | --> lib.rs:1:1 133 | | 134 | 1 | pub fn foo() {} 135 | | ^^^^^^^^^^^^ 136 | 137 | error: aborting due to 2 previous errors 138 | ``` 139 | 140 | 您还可以多次传递每个标志,以更改多个Lint: 141 | 142 | ```bash 143 | $ rustc lib.rs --crate-type=lib -D missing-docs -D unused-variables 144 | ``` 145 | 146 | 当然,您可以将这四个标志混合在一起: 147 | 148 | ```bash 149 | $ rustc lib.rs --crate-type=lib -D missing-docs -A unused-variables 150 | ``` 151 | 152 | #### 通过属性 153 | 154 | 还可以使用crate范围的属性修改Lint级别: 155 | 156 | ```bash 157 | $ cat lib.rs 158 | #![warn(missing_docs)] 159 | 160 | pub fn foo() {} 161 | $ rustc lib.rs --crate-type=lib 162 | warning: missing documentation for crate 163 | --> lib.rs:1:1 164 | | 165 | 1 | / #![warn(missing_docs)] 166 | 2 | | 167 | 3 | | pub fn foo() {} 168 | | |_______________^ 169 | | 170 | note: lint level defined here 171 | --> lib.rs:1:9 172 | | 173 | 1 | #![warn(missing_docs)] 174 | | ^^^^^^^^^^^^ 175 | 176 | warning: missing documentation for a function 177 | --> lib.rs:3:1 178 | | 179 | 3 | pub fn foo() {} 180 | | ^^^^^^^^^^^^ 181 | ``` 182 | 183 | 所有四种等级,`warn`,`allow`,`deny`,和`forbid`,都可以这样工作。 184 | 185 | 您还可以为每个属性传递多个Lint: 186 | 187 | ```rust 188 | #![warn(missing_docs, unused_variables)] 189 | 190 | pub fn foo() {} 191 | ``` 192 | 193 | 并一起使用多个属性: 194 | 195 | ```rust 196 | #![warn(missing_docs)] 197 | #![deny(unused_variables)] 198 | 199 | pub fn foo() {} 200 | ``` 201 | 202 | ### 封顶Lint 203 | 204 | `rustc` 支持 `--cap-lints LEVEL` 的标志来设置“Lint上限” 。这是所有Lint的最高等级。因此,例如,如果我们从上面的“ deny” lint级别获取代码示例: 205 | 206 | ```rust 207 | fn main() { 208 | 100u8 << 10; 209 | } 210 | ``` 211 | 212 | 然后我们对其进行编译,并为Lint封顶警告: 213 | 214 | ```bash 215 | $ rustc lib.rs --cap-lints warn 216 | warning: bitshift exceeds the type's number of bits 217 | --> lib.rs:2:5 218 | | 219 | 2 | 100u8 << 10; 220 | | ^^^^^^^^^^^ 221 | | 222 | = note: `#[warn(exceeding_bitshifts)]` on by default 223 | 224 | warning: this expression will panic at run-time 225 | --> lib.rs:2:5 226 | | 227 | 2 | 100u8 << 10; 228 | | ^^^^^^^^^^^ attempt to shift left with overflow 229 | ``` 230 | 231 | 现在仅警告,而不是错误。我们可以走得更远,并允许所有Lint: 232 | 233 | ```bash 234 | $ rustc lib.rs --cap-lints allow 235 | $ 236 | ``` 237 | 238 | Cargo大量使用此特性;它会使用 `--cap-lints allow` 以便在编译依赖项时通过,这样,即使它们有任何警告,也不会污染生成的输出。 -------------------------------------------------------------------------------- /content/zh-cn/docs/build/lints/lints.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust Lints概述" 3 | linkTitle: "概述" 4 | date: 2021-03-29 5 | weight: 341 6 | description: > 7 | Rust Lints概述 8 | --- 9 | 10 | 在软件中,“Lints”是用于帮助改善源代码的工具。Rust编译器包含许多Lints,并且在编译代码时,它还将运行Lints。这些Lints可能会产生警告,错误或根本不产生任何东西,具体取决于您配置事物的方式。 11 | 12 | 这是一个小例子: 13 | 14 | ```bash 15 | $ cat main.rs 16 | fn main() { 17 | let x = 5; 18 | } 19 | $ rustc main.rs 20 | warning: unused variable: `x` 21 | --> main.rs:2:9 22 | | 23 | 2 | let x = 5; 24 | | ^ 25 | | 26 | = note: `#[warn(unused_variables)]` on by default 27 | = note: to avoid this warning, consider using `_x` instead 28 | ``` 29 | 30 | 这是`unused_variables` Lints,它告诉您已引入了代码中的变量未使用。这不是*bug*,所以它不是一个错误,但它可能是一个错误,所以你得到一个警告。 -------------------------------------------------------------------------------- /content/zh-cn/docs/build/module/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust Module" 3 | linkTitle: "Module" 4 | weight: 330 5 | date: 2021-03-29 6 | description: > 7 | Rust Module 8 | --- 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/zh-cn/docs/build/module/images/rust-module-system-explanation/rust-module-system-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/content/zh-cn/docs/build/module/images/rust-module-system-explanation/rust-module-system-1.png -------------------------------------------------------------------------------- /content/zh-cn/docs/build/module/images/rust-module-system-explanation/rust-module-system-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/content/zh-cn/docs/build/module/images/rust-module-system-explanation/rust-module-system-2.png -------------------------------------------------------------------------------- /content/zh-cn/docs/build/module/images/rust-module-system-explanation/rust-module-system-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/content/zh-cn/docs/build/module/images/rust-module-system-explanation/rust-module-system-3.png -------------------------------------------------------------------------------- /content/zh-cn/docs/build/module/images/rust-module-system-explanation/rust-module-system-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/content/zh-cn/docs/build/module/images/rust-module-system-explanation/rust-module-system-4.png -------------------------------------------------------------------------------- /content/zh-cn/docs/build/module/images/rust-module-system-explanation/rust-module-system-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/content/zh-cn/docs/build/module/images/rust-module-system-explanation/rust-module-system-5.png -------------------------------------------------------------------------------- /content/zh-cn/docs/build/module/rust-programming-langurage/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust编程语言:使用package,crate和module来管理成长中的项目" 3 | linkTitle: "Rust编程语言" 4 | weight: 333 5 | date: 2021-11-06 6 | description: > 7 | Rust编程语言:使用package,crate和module来管理成长中的项目 8 | --- 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/zh-cn/docs/build/module/rust-programming-langurage/defining-modules-to-control-scope-and-privacy.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "定义模块以控制范围和隐私" 3 | linkTitle: "定义模块以控制范围和隐私" 4 | weight: 3 5 | date: 2021-11-06 6 | description: > 7 | 定义模块以控制范围和隐私 8 | --- 9 | 10 | https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html 11 | 12 | 在这一节中,我们将讨论模块和模块系统的其他部分,即允许你命名项目的路径;将路径带入范围的 `use` 关键字;以及使项目 public 的 `pub` 关键字。我们还将讨论 `as` 关键字、外部包和 `glob` 操作符。现在,让我们把重点放在模块上吧! 13 | 14 | 模块让我们把 crate 中的代码组织成一组,以提高可读性并便于重复使用。模块还可以控制项目的私密性,也就是一个项目是可以被外部代码使用(public)还是属于内部实现的细节(private),不能被外部使用。 15 | 16 | 作为例子,让我们写一个提供餐厅功能的crate。我们将定义函数的签名,但将其主体留空,以集中精力组织代码,而不是在代码中实际实现一个餐厅。 17 | 18 | 在餐饮业中,餐厅的某些部分被称为前厅,其他部分被称为后厅。前厅是顾客所在的地方;这里是主人为顾客安排座位,服务员接受订单和付款,调酒师调制饮料的地方。后厨是厨师在厨房工作的地方,洗碗工负责清理,经理负责行政工作。 19 | 20 | 为了按照真正的餐厅的工作方式来组织我们的 crate,我们可以将这些功能组织成嵌套模块。通过运行 `cargo new --lib restaurant` 创建一个名为 `restaurant` 的新库;然后将清单 7-1 中的代码放入 `src/lib.rs`,以定义一些模块和函数签名。 21 | 22 | 文件名:`src/lib.rs`: 23 | 24 | ```rust 25 | mod front_of_house { 26 | mod hosting { 27 | fn add_to_waitlist() {} 28 | 29 | fn seat_at_table() {} 30 | } 31 | 32 | mod serving { 33 | fn take_order() {} 34 | 35 | fn serve_order() {} 36 | 37 | fn take_payment() {} 38 | } 39 | } 40 | ``` 41 | 42 | 清单 7-1: 包含其他模块的 `front_of_house` 模块,这些模块又包含函数。 43 | 44 | 我们以 `mod` 关键字开始定义模块,然后指定模块的名称(本例中为 `front_of_house`),并在模块的主体周围加上大括号。在模块内部,我们可以有其他的模块,如本例中的 `hosting` 和 `serving` 模块。模块还可以容纳其他项目的定义,如结构体、枚举、常量、特征,或如清单7-1中的函数。 45 | 46 | 通过使用模块,我们可以将相关的定义组合在一起,并说明它们为什么相关。使用这段代码的程序员会更容易找到他们想要使用的定义,因为他们可以根据分组来浏览代码,而不必阅读所有的定义。为这段代码添加新功能的程序员会知道该把代码放在哪里,以保持程序的条理性。 47 | 48 | 早些时候,我们提到 `src/main.rs` 和 `src/lib.rs` 被称为 `crate roots`。之所以叫这个名字,是因为这两个文件中的任何一个文件的内容都构成了一个名为 `crate` 的模块,位于 `crate` 模块结构的根部,也就是所谓的模块树(*module tree*)。 49 | 50 | 清单 7-2 显示了清单 7-1 中结构的模块树: 51 | 52 | ```bash 53 | crate 54 | └── front_of_house 55 | ├── hosting 56 | │ ├── add_to_waitlist 57 | │ └── seat_at_table 58 | └── serving 59 | ├── take_order 60 | ├── serve_order 61 | └── take_payment 62 | ``` 63 | 64 | 清单7-2:清单7-1中代码的模块树 65 | 66 | 这棵树显示了一些模块是如何相互嵌套的(例如,`hosting` 嵌套在 `front_of_house` 里面)。这棵树还显示一些模块是彼此的兄弟姐妹,这意味着它们被定义在同一个模块中(`hosting` 和 `serving` 被定义在 `front_of_house` 中)。为了继续这个家庭隐喻,如果模块A包含在模块B里面,我们就说模块A是模块B的孩子,模块B是模块A的父母。请注意,整个模块树的根在名为crate的隐式模块下。 67 | 68 | 模块树可能会让你想起你电脑上的文件系统的目录树;这是一个非常恰当的比较!就像文件系统的目录一样。就像文件系统中的目录,你用模块来组织你的代码。就像目录中的文件一样,我们需要一种方法来找到我们的模块。 69 | 70 | -------------------------------------------------------------------------------- /content/zh-cn/docs/build/module/rust-programming-langurage/module-system.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "模块系统" 3 | linkTitle: "模块系统" 4 | weight: 1 5 | date: 2021-11-06 6 | description: > 7 | Rust编程语言:模块系统 8 | --- 9 | 10 | https://doc.rust-lang.org/book/ch07-00-managing-growing-projects-with-packages-crates-and-modules.html 11 | 12 | 编写大型程序时,组织代码将是很重要的,因为在头脑中保持对整个程序的跟踪将变得不可能。通过对相关功能进行分组,并将具有不同特征的代码分开,你将明确在哪里可以找到实现某个特定功能的代码,以及在哪里可以改变某个功能的工作方式。 13 | 14 | 到目前为止,我们所写的程序都是在单个文件的单个模块中。随着项目的发展,可以通过把代码分成多个模块,然后再分成多个文件来组织代码。一个 package 可以包含多个二进制 crate,也可以选择一个库 crate。随着 package 的增长,可以将部分内容提取到独立的 crate 中,成为外部依赖。本章涵盖了所有这些技术。对于由一组相互关联的 package 组成的、共同发展的大型项目,Cargo提供了工作空间,我们将在第14章的 "Cargo工作空间" 部分介绍。 15 | 16 | 除了对功能进行分组外,封装实现细节还可以让你在更高层次上重用代码:一旦你实现了某个操作,其他代码就可以通过代码的 public 接口调用该代码,而不需要知道实现是如何工作的。你写代码的方式定义了哪些部分是 public 的,供其他代码使用,哪些部分是 private 的实现细节,你保留改变的权利。这是另一种限制你必须记在脑子里的细节数量的方法。 17 | 18 | `scope` 是一个相关的概念:编写代码的嵌套上下文有一组被定义为 "in scope" 的名称。在阅读、编写和编译代码时,程序员和编译器需要知道某个特定位置的特定名称是否指的是一个变量、函数、结构体、枚举、模块、常量或其他项目,以及该项目意味着什么。你可以创建作用域并改变哪些名字在作用域内或作用域外。你不能在同一个作用域中有两个同名的项目;有工具可以解决名称冲突。 19 | 20 | Rust有很多功能可以让你管理代码组织,包括哪些细节是 public 的,哪些细节是 private 的,以及在程序中每个范围内有哪些名字。这些功能,有时被统称为模块系统,包括: 21 | 22 | - **Package**: Cargo 的一个功能,可以建立、测试和分享 crate。 23 | 24 | - **Crate**:一个模块树,产生一个库或可执行文件 25 | 26 | - **Module** 和 **use**: 让你控制路径的组织、范围和隐私 27 | 28 | - **Path**:命名项目的方式,如结构体、函数或模块 29 | 30 | 在本章中,我们将介绍所有这些功能,讨论它们如何相互作用,并解释如何使用它们来管理范围。到最后,你应该对模块系统有一个扎实的了解,并且能够像专家一样使用作用域。 31 | -------------------------------------------------------------------------------- /content/zh-cn/docs/build/module/rust-programming-langurage/packages-and-crates.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Package和Crate" 3 | linkTitle: "Package和Crate" 4 | weight: 2 5 | date: 2021-11-06 6 | description: > 7 | Package和Crate 8 | --- 9 | 10 | https://doc.rust-lang.org/book/ch07-01-packages-and-crates.html 11 | 12 | 我们要讨论的模块系统的第一部分是 package 和 crate。crate 是一个二进制文件或库。crate root 是一个源文件,Rust编译器从它开始,构成了你的crate的根模块(我们将在 "定义模块以控制范围和隐私" 部分深入解释模块)。包是一个或多个提供一系列功能的crate。Package 包含一个 `Cargo.toml` 文件,描述如何构建这些 crate。 13 | 14 | 一些规则决定了 package 可以包含什么。一个 package 最多可以包含一个库crate。它可以包含任何你想要的二进制crate,但它必须至少包含一个crate(无论是库还是二进制)。 15 | 16 | 让我们来看看我们创建一个 package 时发生了什么。首先,我们输入 `cargo new` 命令: 17 | 18 | ```bash 19 | $ cargo new my-project 20 | Created binary (application) `my-project` package 21 | $ ls my-project 22 | Cargo.toml 23 | src 24 | $ ls my-project/src 25 | main.rs 26 | ``` 27 | 28 | 当我们输入命令时,Cargo创建了一个 `Cargo.toml` 文件,给了我们一个 package。看一下 `Cargo.toml` 的内容,没有提到 `src/main.rs`,因为 Cargo 遵循的惯例是 `src/main.rs` 是与 package 同名的二进制 crate 的 crate 根。同样地,Cargo 知道如果包的目录中包含 `src/lib.rs`,那么该 package 就包含一个与该 package 同名的库 crate,而 `src/lib.rs` 是其 crate 根。Cargo 会将 crate 根文件传递给 rustc 来构建库或二进制文件。 29 | 30 | 这里,我们有一个只包含 `src/main.rs` 的 package,意味着它只包含一个名为 `my-project` 的二进制 crate。如果一个包包含 `src/main.rs` 和 `src/lib.rs`,那么它就有两个crate:一个库和一个二进制,两者的名字都与包相同。通过在 `src/bin` 目录中放置文件,一个包可以有多个二进制 crate:每个文件都是一个单独的二进制 crate。 31 | 32 | 一个 crate 将把相关的功能集中在一个范围内,这样功能就很容易在多个项目之间共享。例如,我们在第二章中使用的 `rand` crate 提供了生成随机数的功能。我们可以在自己的项目中使用该功能,方法是将 `rand` crate 带入我们项目的作用域。所有由 `rand` crate 提供的功能都可以通过 crate 的名称 `rand` 来访问。 33 | 34 | 将 crate 的功能保留在自己的范围内,可以明确特定的功能是在我们的 crate 还是rand crate 中定义的,并防止潜在的冲突。例如,`rand` crate 提供了一个名为 `Rng` 的 trait。我们也可以在自己的 crate 中定义一个名为 `Rng` 的结构。因为 crate 的功能是在它自己的范围内命名的,所以当我们添加 `rand` 作为依赖关系时,编译器不会对 `Rng` 这个名字的含义感到困惑。在我们的 crate 中,它指的是我们定义的 `Rng` 结构体。我们将从 `rand` crate 中访问 `Rng` 的特性,即 `rand::Rng` 。 35 | 36 | 让我们继续谈一谈模块系统吧。 37 | -------------------------------------------------------------------------------- /content/zh-cn/docs/build/module/rust-programming-langurage/separating-modules-into-different-files.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "将模块分离到不同的文件中" 3 | linkTitle: "将模块分离到不同的文件中" 4 | weight: 5 5 | date: 2021-11-06 6 | description: > 7 | 将模块分离到不同的文件中 8 | --- 9 | 10 | https://doc.rust-lang.org/book/ch07-05-separating-modules-into-different-files.html 11 | 12 | 到目前为止,本章中所有的例子都是在一个文件中定义多个模块。当模块变得很大时,你可能想把它们的定义移到一个单独的文件中,以使代码更容易浏览。 13 | 14 | 例如,让我们从清单7-17中的代码开始,将 `front_of_house` 模块移到它自己的文件 `src/front_of_house.rs` 中,改变 crate root 文件,使其包含清单7-21中的代码。在这个例子中,crate root 文件是 `src/lib.rs`,但这个过程也适用于 crate root 文件为 `src/main.rs` 的二进制crate。 15 | 16 | 文件名:src/lib.rs 17 | 18 | ```rust 19 | mod front_of_house; 20 | 21 | pub use crate::front_of_house::hosting; 22 | 23 | pub fn eat_at_restaurant() { 24 | hosting::add_to_waitlist(); 25 | hosting::add_to_waitlist(); 26 | hosting::add_to_waitlist(); 27 | } 28 | ``` 29 | 30 | 清单 7-21: 声明 `front_of_house` 模块,其主体将在 `src/front_of_house.rs` 中。 31 | 32 | 而 `src/front_of_house.rs` 则从 `front_of_house` 模块的主体中获取定义,如清单 7-22 所示。 33 | 34 | 文件名:`src/front_of_house.rs` 35 | 36 | ```rust 37 | pub mod hosting { 38 | pub fn add_to_waitlist() {} 39 | } 40 | ``` 41 | 42 | 清单 7-22: `src/front_of_house.rs` 中 `front_of_house` 模块内部的定义 43 | 44 | 在 `mod front_of_house` 后面使用分号,而不是使用块,是告诉 Rust 从与该模块同名的另一个文件中加载该模块的内容。为了继续我们的例子并将 hosting 模块也提取到自己的文件中,我们将 `src/front_of_house.rs` 改为只包含 hosting 模块的声明。 45 | 46 | 文件名:`src/front_of_house.rs` 47 | 48 | ```rust 49 | pub mod hosting; 50 | ``` 51 | 52 | 然后我们创建一个 `src/front_of_house` 目录和一个 `src/front_of_house/hosting.rs` 文件,以包含 hosting 模块中的定义。 53 | 54 | 文件名:`src/front_of_house/hosting.rs` 55 | 56 | ```rust 57 | pub fn add_to_waitlist() {} 58 | ``` 59 | 60 | 模块树保持不变,`eat_at_restaurant` 中的函数调用将不做任何修改,即使定义在不同的文件中。这种技术可以让你在模块体积增大时将其移到新的文件中。 61 | 62 | 注意 `src/lib.rs` 中的 `pub use crate::front_of_house::hosting` 语句也没有改变,使用也不会对哪些文件作为 `crate` 的一部分被编译产生任何影响。mod 关键字声明了模块,Rust 会在与模块同名的文件中寻找进入该模块的代码。 63 | 64 | ## 总结 65 | 66 | Rust允许你把包分成多个crate,把crate 分成模块,这样你就可以从另一个模块引用一个模块中定义的项目。你可以通过指定绝对或相对路径来做到这一点。这些路径可以被带入使用语句的范围内,这样你就可以在该范围内使用一个较短的路径来多次使用该项目。模块代码默认是私有的,但你可以通过添加pub关键字使定义公开。 67 | 68 | -------------------------------------------------------------------------------- /content/zh-cn/docs/build/rustc/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rustc" 3 | linkTitle: "Rustc" 4 | weight: 310 5 | date: 2021-03-29 6 | description: > 7 | Rustc 8 | --- 9 | 10 | 11 | 12 | ### 介绍 13 | 14 | `rustc`是 Rust 编程语言的编译器,由项目组开发提供。编译器将您的源代码和生产二进制代码,变成一个或可执行文件。 15 | 16 | 大多数 Rust 程序员都不会直接调用`rustc`,而是通过[Cargo](http://llever.com/cargo/index.html)来完成,虽然Cargo也是调用`rustc`流程!如果想看看 Cargo 如何调用`rustc`, 可以 17 | 18 | ```bash 19 | $ cargo build --verbose 20 | ``` 21 | 22 | 它会打印出每个`rustc`调用。 23 | 24 | ### 资料 25 | 26 | - [The rustc book](https://doc.rust-lang.org/rustc/index.html): 官方英文版 27 | - [The rustc book](http://llever.com/rustc-zh/): 中文翻译版。备注:经常打不开,需要科学上网。另外lint相关的内容和英文文档的内容有很大的偏差。 -------------------------------------------------------------------------------- /content/zh-cn/docs/build/rustc/conditional-compilation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rustc的条件编译" 3 | linkTitle: "条件编译" 4 | date: 2021-03-29 5 | weight: 313 6 | description: > 7 | Rustc的条件编译 8 | --- 9 | 10 | ## 介绍 11 | 12 | ### 什么是条件编译? 13 | 14 | 条件编译是指根据某些条件来决定特性代码是否被视为源代码的一部分。 15 | 16 | 可以使用属性 cfg 和 cfg_attr,还有内置 cfg 宏来有条件地编译源代码。这些条件基于:已编译的crate的目标体系结构,传递给编译器的任意值,以及其他一些杂项。 17 | 18 | 19 | 20 | ### 配置谓词 21 | 22 | 条件编译的每种形式都采用评估加过为 true 或 false 的配置谓词(configuration predicate)。谓词是以下之一: 23 | 24 | - 配置选项。如果设置了该选项,则为true;如果未设置,则为false。 25 | - all() 用逗号分隔的配置谓词列表。只要有一个谓词为false,则为false。如果没有谓词,那就是true。 26 | - any() 用逗号分隔的配置谓词列表。如果至少一个谓词为true,则为true。如果没有谓词,则为false。 27 | - not() 带有配置谓词。如果其谓词为false,则为true;如果其谓词为true,则为false。 28 | 29 | ### 配置选项 30 | 31 | 配置选项是已设置或未设置的 name 和 key-value 对。name 被写为单个标识符,例如 `unix`。key-value 对被写为标识符,=,然后是字符串。例如,`target_arch = "x86_64"` 是一个配置选项。 32 | 33 | > 注意:等号周围的空格将被忽略。`foo="bar"` 和 `foo = "bar"` 是等同的配置选项。 34 | 35 | 键在键值配置选项集中不是唯一的。例如,`feature = "std"` 和 `feature = "serde"` 可以同时设置。 36 | 37 | ## 设置配置选项 38 | 39 | 设置哪些配置选项是在板条箱的编译过程中静态确定的。某些选项在*编译器集合*根据有关统计数据。其他选项是*任意设置*,基于代码外传递给编译器的输入进行设置。无法从正在编译的板条箱的源代码中设置配置选项。 40 | 41 | > **注意**:对于`rustc`,可以使用[`--cfg`](https://doc.rust-lang.org/rustc/command-line-arguments.html#--cfg-configure-the-compilation-environment)标志设置任意设置的配置选项 。 42 | 43 | 警告:任意设置的配置选项可能与编译器设置的配置选项具有相同的值。例如,可以`rustc --cfg "unix" program.rs`在编译到Windows目标时进行,并同时设置`unix`和`windows`配置选项。实际执行此操作是不明智的。 44 | 45 | 46 | 47 | 48 | `#[cfg]` 是 Rust 的特殊属性,,允许基于传递给编译器的标记来编译代码。有两种形式: 49 | 50 | ``` 51 | #[cfg(foo)] 52 | 53 | #[cfg(bar = "baz")] 54 | ``` 55 | 56 | 所有的条件编译都由通过cfg配置实现,cfg支持any、all、not等逻辑谓词组合。 57 | 58 | 59 | 60 | 61 | 它还有一些帮助选项: 62 | 63 | ``` 64 | #[cfg(any(unix, windows))] 65 | 66 | #[cfg(all(unix, target_pointer_width = "32"))] 67 | 68 | #[cfg(not(foo))] 69 | ``` 70 | 71 | 这些选项可以任意嵌套: 72 | 73 | ``` 74 | #[cfg(any(not(unix), all(target_os="macos", target_arch = "powerpc")))] 75 | ``` 76 | 77 | 至于如何启用和禁用这些开关,如果使用Cargo的话,可以在 `Cargo.toml`中的[`[features\]`部分](http://doc.crates.io/manifest.html#the-[features]-section)设置: 78 | 79 | ``` 80 | [features] 81 | # no features by default 82 | default = [] 83 | 84 | # The “secure-password” feature depends on the bcrypt package. 85 | secure-password = ["bcrypt"] 86 | ``` 87 | 88 | 这时,Cargo会传递给 `rustc` 一个标记: 89 | 90 | ``` 91 | --cfg feature="${feature_name}" 92 | ``` 93 | 94 | 这些`cfg`标记集合会决定哪些功能被启用,哪些代码会被编译。让我们看看这些代码: 95 | 96 | ``` 97 | #[cfg(feature = "foo")] 98 | mod foo { 99 | } 100 | ``` 101 | 102 | 如果你用`cargo build --features "foo"`编译,他会向`rustc`传递`--cfg feature="foo"`标记,并且输出中将会包含`mod foo`。如果我们使用常规的`cargo build`编译,则不会传递额外的标记,因此,(输出)不会存在`foo`模块。 103 | 104 | ## cfg_attr 105 | 106 | 你也可以通过一个基于`cfg`变量的`cfg_attr`来设置另一个属性: 107 | 108 | ``` 109 | #[cfg_attr(a, b)] 110 | ``` 111 | 112 | 如果`a`通过`cfg`属性设置了的话这与`#[b]`相同,否则不起作用。 113 | 114 | # cfg! 115 | 116 | `cfg!`[语法扩展](http://doc.rust-lang.org/nightly/book/compiler-plugins.html)也让你可以在你的代码中使用这类标记: 117 | 118 | ``` 119 | if cfg!(target_os = "macos") || cfg!(target_os = "ios") { 120 | println!("Think Different!"); 121 | } 122 | ``` 123 | 124 | 这会在编译时被替换为一个`true`或`false`,依配置设定而定。 125 | 126 | ### 参考资料 127 | 128 | - [Conditional compilation@the rust reference]([Conditional compilation](https://doc.rust-lang.org/reference/conditional-compilation.html#conditional-compilation)) 129 | - [条件编译@rust book 中文翻译](https://www.kancloud.cn/thinkphp/rust/36050) 130 | - [Rust 交叉编译与条件编译总结](https://www.jianshu.com/p/0e4251bc10eb) 131 | 132 | -------------------------------------------------------------------------------- /content/zh-cn/docs/build/rustup/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rustup" 3 | linkTitle: "Rustup" 4 | weight: 390 5 | date: 2021-10-21 6 | description: > 7 | Rust安装程序 8 | --- 9 | 10 | -------------------------------------------------------------------------------- /content/zh-cn/docs/build/rustup/rustup.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rustup概述" 3 | linkTitle: "Rustup概述" 4 | weight: 391 5 | date: 2021-10-21 6 | description: > 7 | Rust安装程序 8 | --- 9 | 10 | 11 | 12 | ## 介绍 13 | 14 | rustup 是系统编程语言Rust的安装程序。 15 | 16 | rustup 从官方发布渠道安装Rust编程语言,使你能够在稳定版、测试版和nightly编译器之间轻松切换并保持更新。它使交叉编译变得更加简单,为普通平台的标准库建立二进制。而且它可以在Rust支持的所有平台上运行。 17 | 18 | ### 相关信息 19 | 20 | - https://rustup.rs/ 21 | 22 | - [rustup book](https://rust-lang.github.io/rustup/index.html): 对rustup有详细介绍 23 | 24 | ## 常用命令 25 | 26 | ### 安装rust 27 | 28 | ```bash 29 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 30 | ``` 31 | 32 | ### 更新rust 33 | 34 | ```bash 35 | rustup update 36 | ``` 37 | 38 | ### 卸载rust 39 | 40 | ```bash 41 | rustup self uninstall 42 | ``` 43 | 44 | ### 打开本地文档 45 | 46 | rust安装时会在本地生成一份离线文档,可以用下面的命令在浏览器中打开: 47 | 48 | ```bash 49 | rustup doc 50 | ``` 51 | 52 | ### 安装目标平台的标准库 53 | 54 | `rustup target` 命令安装目标平台的标准库 55 | 56 | ```bash 57 | rustup target add arm-linux-androideabi 58 | ``` 59 | 60 | 61 | 62 | ## 镜像安装 63 | 64 | 参考: https://mirrors.tuna.tsinghua.edu.cn/help/rustup/ 65 | 66 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust语法" 3 | linkTitle: "语法" 4 | weight: 2000 5 | date: 2021-03-29 6 | description: > 7 | Rust语法 8 | --- 9 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/basic/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust基本语法" 3 | linkTitle: "基本语法" 4 | weight: 1100 5 | date: 2021-03-29 6 | description: > 7 | Rust的基本语法 8 | --- -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/basic/comment.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的注释" 3 | linkTitle: "注释" 4 | date: 2021-03-29 5 | weight: 1150 6 | description: > 7 | Rust的注释 8 | --- 9 | 10 | Rust的注释有两种: 11 | 12 | 1. 普通注释 13 | - `//` 对整行进行注释 14 | - `/* .. */` 对区块注释 15 | 2. 文档注释 16 | - `///` 生成库文档,一般用于函数或者结构体的说明,置于说明对象的上方 17 | - `//!` 也生成库文档,一般用于说明整个模块的功能,置于模块文件的头部 18 | 19 | 示例: 20 | 21 | ```rust 22 | /// # 文档注释: Sum函数 23 | /// 该函数为求和函数 24 | /// # usage: 25 | /// assert_eq!(3, sum(1, 2)); 26 | fn sum(a: i32, b: i32) -> i32 { 27 | a + b 28 | } 29 | pub fn annotation() { 30 | // 这是单行注释的示例 31 | /* 32 | * 这是区块注释, 被包含的区域都会被注释 33 | * 你可以把/* 区块 */ 置于代码中的任何位置 34 | */ 35 | /* 36 | 注意上面区块注释中的*符号,纯粹是一种注释风格, 37 | 实际并不需要 38 | */ 39 | let x = 5 + /* 90 + */ 5; 40 | println!("Is `x` 10 or 100? x = {}", x); 41 | println!("2 + 3 = {}", sum(2, 3)); 42 | } 43 | ``` 44 | 45 | ### 文档注释 46 | 47 | 文档注释支持 markdown !! 48 | 49 | 还支持对文档中的示例代码进行测试,可以用 rustdoc 工具生成 50 | HTML 文档 51 | 52 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/basic/const.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的常量" 3 | linkTitle: "常量" 4 | date: 2021-03-29 5 | weight: 1110 6 | description: > 7 | Rust的常量 8 | --- 9 | 10 | 常量是绑定到一个名称的不允许改变的值。 11 | 12 | 常量与不可变变量的区别: 13 | 14 | - 不允许对常量使用 `mut` 15 | - 声明常量使用 `const` 关键字而不是 `let`,并且 *必须* 注明值的类型。 16 | - 常量只能被设置为常量表达式,而不能是函数调用的结果,或任何其他只能在运行时计算出的值 17 | 18 | 备注:rust的常量是必须在编译时明确赋值的。 19 | 20 | 声明常量的例子: 21 | 22 | ```rust 23 | const MAX_POINTS: u32 = 100_000; 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/basic/expression.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的表达式" 3 | linkTitle: "表达式" 4 | date: 2021-03-29 5 | weight: 1140 6 | description: > 7 | Rust的表达式 8 | --- 9 | 10 | 表达式主要用于计算求值。 11 | 12 | Rust 编译器在解析代码时: 13 | 14 | - 如果遇到分号,就会继续往后面执行 15 | - 如果遇到语句,就会执行语句 16 | - 如果遇到表达式,就会对表达式求值 17 | - 如果分号后面什么都没有,就会补上单元值`()` 18 | - 当遇到函数时,就会将函数体的花括号识别为块表达式。 19 | 20 | ### 块表达式 21 | 22 | 块表达式是由一对花括号和一系列表达式组成的,它总是返回块中最后一个表达式的值。 23 | 24 | ### 位置表达式 25 | 26 | 位置表达式(Place Expression)一般叫做左值,是表示内存位置的表达式,有以下几类: 27 | 28 | - 本地变量 29 | - 静态变量 30 | - 解引用 (* express) 31 | - 数组索引 (expr[expr]) 32 | - 字段引用 (expr.field) 33 | - 位置表达式组合 34 | 35 | 通过位置表达式可以对某个数据单元的内存进行读写。位置表达式可以用于赋值。 36 | 37 | ### 值表达式 38 | 39 | 值表达式(Value Expression)一般叫做右值,值表达式引用了某个存储单元地址中的数据。它相当于数据,只能进行读操作。 40 | 41 | 从语义角度来说,**位置表达式代表了持久性数据,值表达式代表了临时数据**。位置表达式一般有持久的状态,值表达式要不是字面量,要不就是表达式求值过程中创建的临时值。 42 | 43 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/basic/print.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的打印" 3 | linkTitle: "打印" 4 | date: 2021-03-29 5 | weight: 1160 6 | description: > 7 | Rust的打印 8 | --- 9 | 10 | 打印操作由[`std::fmt`](http://doc.rust-lang.org/std/fmt/)里面所定义的一系列宏来处理,包括: 11 | 12 | - `format!`:将格式化文本输出到 `字符串`(String) 13 | - `print!`:与 `format!`类似,但将文本输出到控制台 14 | - `println!`: 与 `print!`类似,但输出结果追加一个换行符 15 | 16 | 17 | 18 | 详细的使用说明见rust官方文档: 19 | 20 | https://doc.rust-lang.org/1.0.0/std/fmt/index.html -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/basic/return.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的返回值" 3 | linkTitle: "返回值" 4 | date: 2021-03-29 5 | weight: 1170 6 | description: > 7 | Rust的返回值 8 | --- 9 | 10 | ### 为什么使用返回值而不是异常 11 | 12 | [Why Rust uses Return Values for errors instead of Exceptions](https://mattgathu.github.io/why-rust-return-values-errors/) 13 | 14 | 我经常问自己,为什么Rust中的错误处理使用返回值而不是异常,在此进行解释,我引用在这里以备将来。 15 | 16 | > 有些人需要在不允许使用 Exception 的地方使用Rust(因为展开表和清理代码太大)。这些人实际上包括所有浏览器供应商和游戏开发人员。此外, Exception 具有讨厌的代码生成权衡。您要么将它们设为零成本(如C ++,Obj-C和Swift编译器通常所做的那样),在这种情况下,在运行时抛出异常的代价非常高,或者使它们成为非零成本(如Java HotSpot和Go 6g/8g),在这种情况下,即使没有引发异常,您也会为每个 try 块(在Go中为defer)牺牲性能。对于使用RAII的语言,每个带有析构函数的堆栈对象都形成一个隐式try块,因此在实践中这是不切实际的。 17 | > 18 | > 零成本 Exception 的性能开销不是理论问题。我记得关于使用GCJ(使用零成本 Exception)进行编译时,Eclipse 需要花费30秒来启动的故事,因为它在启动时会引发数千个 Exception。 19 | > 20 | > 当您同时考虑错误和成功路径时,相对于 Exception,C处理错误的方法具有出色的性能和代码大小,这就是为什么系统代码非常喜欢它的原因。然而,它的人机工程学和安全性很差,Rust用Result来解决。Rust的方法形成了一种混合体,旨在实现C错误处理的性能,同时消除其陷阱。 -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/basic/statement.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的语句" 3 | linkTitle: "语句" 4 | date: 2021-03-29 5 | weight: 1130 6 | description: > 7 | Rust的语句 8 | --- 9 | 10 | 语句是指要执行的一些操作和产生副作用的表达式。 11 | 12 | 语句分为两种: 13 | 14 | ## 声明语句 15 | 16 | 用于声明各种语言项,包括声明变量,静态变量,常量,结构体,函数等,以及通过 extern 和 use 关键字引入包和模块等。 17 | 18 | ## 表达式语句 19 | 20 | 特指以分号结束的表达式。此类表达式求值结果将会被舍弃,并总是返回单元类型`()`。 21 | 22 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/basic/variable.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的变量" 3 | linkTitle: "变量" 4 | date: 2021-03-29 5 | weight: 1120 6 | description: > 7 | Rust的变量 8 | --- 9 | 10 | ## 不可变变量 11 | 12 | 变量默认是不可改变的(immutable),这是Rust 提供的安全性和简单并发性来编写代码的众多方式之一。 13 | 14 | let 关键字用于定义变量,默认定义的是不可变变量: 15 | 16 | ```rust 17 | fn main() { 18 | // 可以通过类型推导得到变量类型,因此可以不制定变量类型 19 | let a = 1; 20 | // 也可以明确指定变量类型 21 | let b: bool = true; 22 | } 23 | ``` 24 | 25 | Rust 编译器保证,如果声明一个值不会变,它就真的不会变。这意味着当阅读和编写代码时,不需要追踪一个值如何和在哪可能会被改变,从而使得代码易于推导。 26 | 27 | ## 可变变量 28 | 29 | 变量只是默认不可变;正如在第二章所做的那样,你可以在变量名之前加 mut 来使其可变。除了允许改变值之外,mut 向读者表明了其他代码将会改变这个变量值的意图。 30 | 31 | ```rust 32 | fn main() { 33 | let mut x = 5; 34 | println!("The value of x is: {}", x); 35 | x = 6; 36 | println!("The value of x is: {}", x); 37 | } 38 | ``` 39 | 40 | ## 权衡使用 41 | 42 | - 使用大型数据结构时,适当地使用可变变量,可能比复制和返回新分配的实例更快 43 | - 对于较小的数据结构,总是创建新实例,采用更偏向函数式的编程风格,可能会使代码更易理解,为可读性而牺牲性能或许是值得的 44 | 45 | 当多种类型均有可能时,必须增加类型注解: 46 | 47 | ```rust 48 | let guess: u32 = "42".parse().expect("Not a number!"); 49 | ``` 50 | 51 | ## 变量隐藏 52 | 53 | 可以定义一个与之前变量同名的新变量,而新变量会 **隐藏(Shadowing)** 之前的变量。 54 | 55 | Rustacean 们称之为第一个变量被第二个 **隐藏** 了,这意味着使用这个变量时会看到第二个值。可以用相同变量名称来隐藏一个变量,以及重复使用 `let` 关键字来多次隐藏,如下所示: 56 | 57 | ```rust 58 | fn main() { 59 | let x = 5; 60 | 61 | let x = x + 1; 62 | 63 | let x = x * 2; 64 | 65 | println!("The value of x is: {}", x); 66 | } 67 | ``` 68 | 69 | 当再次使用 `let` 时,实际上创建了一个新变量,我们可以改变值的类型,但复用这个名字: 70 | 71 | ```rust 72 | let spaces = " "; 73 | let spaces = spaces.len(); 74 | ``` 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/collection/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的集合" 3 | linkTitle: "集合" 4 | weight: 1400 5 | date: 2021-03-29 6 | description: > 7 | Rust的集合 8 | --- 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/collection/binaryheap.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust集合中的优先队列(BinaryHeap)" 3 | linkTitle: "优先队列(BinaryHeap)" 4 | date: 2021-03-29 5 | weight: 1460 6 | description: Rust集合中的优先队列(BinaryHeap) 7 | --- 8 | 9 | Rust 提供的优先队列是基于二叉最大堆(Binary Heap)实现的。 10 | 11 | ```rust 12 | use std::collections::BinaryHeap; 13 | let mut heap = BinaryHeap::new(); 14 | assert_eq!(heap.peek(), None); 15 | heap.push(93); 16 | heap.push(80); 17 | heap.push(48); 18 | heap.push(53); 19 | heap.push(72); 20 | heap.push(30); 21 | heap.push(18); 22 | heap.push(36); 23 | heap.push(15); 24 | heap.push(35); 25 | heap.push(45); 26 | assert_eq!(heap.peek(), Some(&93)); 27 | println!("{:?}", heap); // [93, 80, 48, 53, 72, 30, 18, 36, 15, 35, 45] 28 | ``` 29 | 30 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/collection/deque.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust集合中的双端队列(VecDeque)" 3 | linkTitle: "双端队列(VecDeque)" 4 | date: 2021-03-29 5 | weight: 1420 6 | description: Rust集合中的双端队列(VecDeque) 7 | --- 8 | 9 | Rust 中的 VecDeque 是基于可增长的 RingBuffer 算法实现的双端队列。 10 | 11 | ```rust 12 | use std::collections::VecDeque; 13 | let mut buf = VecDeque::new(); 14 | 15 | buf.push_front(1); 16 | buf.push_front(2); 17 | assert_eq!(buf.get(0), Some(&2)); 18 | assert_eq!(buf.get(1), Some(&1)); 19 | 20 | buf.push_back(3); 21 | buf.push_back(4); 22 | buf.push_back(5); 23 | 24 | assert_eq!(buf.get(2), Some(&3)); 25 | assert_eq!(buf.get(3), Some(&4)); 26 | assert_eq!(buf.get(4), Some(&5)); 27 | ``` 28 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/collection/linkedlist.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust集合中的链表(LinkedList)" 3 | linkTitle: "链表(LinkedList)" 4 | date: 2021-03-29 5 | weight: 1430 6 | description: Rust集合中的链表(LinkedList) 7 | --- 8 | 9 | Rust 提供的链表是双向链表。 10 | 11 | 最好是使用 Vec 或者 VecDeque 类型,比链表更快。 12 | 13 | ```rust 14 | use std::collections::LinkedList; 15 | let mut list1 = LinkedList::new(); 16 | 17 | list1.push_back('a'); 18 | 19 | let mut list2 = LinkedList::new(); 20 | list2.push_back('b'); 21 | list2.push_back('c'); 22 | 23 | list1.append(&mut list2); 24 | println!("{:?}", list1); // ['a', 'b', 'c'] 25 | println!("{:?}", list2); // [] 26 | 27 | list1.pop_front(); 28 | println!("{:?}", list1); // ['b', 'c'] 29 | 30 | list1.push_front('e'); 31 | println!("{:?}", list1); // ['e', 'b', 'c'] 32 | 33 | list2.push_front('f'); 34 | println!("{:?}", list2); // ['f'] 35 | ``` 36 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/collection/map.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust集合中的映射(Map)" 3 | linkTitle: "映射(Map)" 4 | date: 2021-03-29 5 | weight: 1440 6 | description: Rust集合中的映射(Map) 7 | --- 8 | 9 | Rust 提供了两个 Key-Value 哈希映射表: 10 | 11 | - HashMap:无序 12 | - BTreeMap:有序 13 | 14 | 要求:Key 必须是可哈希的类型,Value 必须满足是在编译期已知大小的类型。 15 | 16 | ```rust 17 | use std::collections::BTreeMap; 18 | use std::collections::HashMap; 19 | let mut hmap = HashMap::new(); 20 | let mut bmap = BTreeMap::new(); 21 | hmap.insert(3, "c"); 22 | hmap.insert(1, "a"); 23 | hmap.insert(2, "b"); 24 | hmap.insert(5, "e"); 25 | hmap.insert(4, "d"); 26 | bmap.insert(3, "c"); 27 | bmap.insert(2, "b"); 28 | bmap.insert(1, "a"); 29 | bmap.insert(5, "e"); 30 | bmap.insert(4, "d"); 31 | // 输出结果为:{1: "a", 2: "b", 3: "c", 5: "e", 4: "d"},但key的顺序是随机的,因为HashMap是无序的 32 | println!("{:?}", hmap); 33 | // 输出结果永远都是 {1: "a", 2: "b", 3: "c", 4: "d", 5: "e"},因为BTreeMap是有序的 34 | println!("{:?}", bmap); 35 | ``` 36 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/collection/set.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust集合中的集合(Set)" 3 | linkTitle: "集合(Set)" 4 | date: 2021-03-29 5 | weight: 1450 6 | description: Rust集合中的集合(Set) 7 | --- 8 | 9 | Rust 提供了两个哈希集合: 10 | 11 | - `HashSet`:无序,等同于 HashMap,值为空元组的特定类型 12 | - `BTreeSet`:有序,等同于 BTreeMap,值为空元组的特定类型 13 | 14 | 特性如下: 15 | 16 | - 集合中的元素是唯一的 17 | - 集合中的元素是可哈希的类型 18 | 19 | ```rust 20 | use std::collections::HashSet; 21 | use std::collections::BTreeSet; 22 | let mut hbooks = HashSet::new(); 23 | let mut bbooks = BTreeSet::new(); 24 | // 插入数据 25 | hbooks.insert(2); 26 | hbooks.insert(1); 27 | hbooks.insert(2); 28 | // 判断元素是否存在,contains方法和HashMap中的一样 29 | if !hbooks.contains(&1) { 30 | } 31 | println!("{:?}", hbooks); 32 | bbooks.insert(1); 33 | 34 | bbooks.insert(2); 35 | bbooks.insert(3); 36 | println!("{:?}", bbooks); // 输出固定为 {1, 2, 3} ,因为是有序 37 | ``` 38 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/collection/vec.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust集合中的向量(Vec)" 3 | linkTitle: "向量(Vec)" 4 | date: 2021-03-29 5 | weight: 1410 6 | description: Rust集合中的向量(Vec) 7 | --- 8 | 9 | 向量(Vec) 也是一种数组,差别在于可动态增长。 10 | 11 | ```rust 12 | // 用宏创建可变向量 13 | let mut v1 = vec![]; 14 | v1.push(1); 15 | v1.push(2); 16 | v1.push(3); 17 | assert_eq!(v1, [1,2,3]); 18 | assert_eq!(v1[1], 2); 19 | 20 | // 用宏创建不可变向量 21 | let v2 = vec![0; 10]; 22 | 23 | // 用 new 方法创建 24 | let mut v3 = Vec::new(); 25 | v3.push(4); 26 | v3.push(5); 27 | v3.push(6); 28 | ``` 29 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/flowcontrol/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的流程控制" 3 | linkTitle: "流程控制" 4 | weight: 1600 5 | date: 2021-03-29 6 | description: > 7 | Rust的流程控制 8 | --- 9 | 10 | Rust 中不叫流程控制语句,而是叫做流程控制表达式。 11 | 12 | 这是关键:流程表达式是可以作为右值赋值的 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/flowcontrol/for-in.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的for ... in循环表达式" 3 | linkTitle: "for ... in" 4 | weight: 1620 5 | date: 2021-03-29 6 | description: > 7 | Rust的for ... in循环表达式 8 | --- 9 | 10 | ### 循环表达式 11 | 12 | Rust 有三种循环表达式:while 、loop 和 for ... in 表达式。 13 | 14 | for ... in 循环: 15 | 16 | ```rust 17 | for n in 1..101 { 18 | if n % 15 == 0 { 19 | println!("fizzbuzz"); 20 | } else if n % 3 == 0 { 21 | println!("fizz"); 22 | } else if n % 5 == 0 { 23 | println!("buzz"); 24 | } else { 25 | println!("{}", n); 26 | } 27 | } 28 | ``` 29 | 30 | 注意 for ... in 后面是一个 Rang 类型,左闭右开,所以这个循环的最后一个n值是100。 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/flowcontrol/if-let.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的 if let 表达式" 3 | linkTitle: "if let" 4 | weight: 1660 5 | date: 2021-03-29 6 | description: Rust的 if let 表达式 7 | --- 8 | 9 | 10 | if let 表达式用来在某些场合替代 match 表达式. 11 | 12 | ```rust 13 | let boolean = true; 14 | let mut binary = 0; 15 | // if let 左侧为模式,右侧为匹配的值 16 | if let true = boolean { 17 | binary = 1; 18 | } 19 | assert_eq!(binary, 1); 20 | ``` 21 | 22 | 备注:这个例子看不出 if let 的价值所在。 23 | 24 | 25 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/flowcontrol/if.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的if条件表达式" 3 | linkTitle: "if" 4 | weight: 1610 5 | date: 2021-03-29 6 | description: > 7 | Rust的if条件表达式 8 | --- 9 | 10 | 11 | 表达式一定会有值,所以 if 条件表达式的分支必须返回同一个类型的值。 12 | 13 | ```rust 14 | let n = 13; 15 | // if 表达式可以用来赋值 16 | let big_n = if n < 10 && n > -10 { 17 | // 分支必须返回同一个类型的值 18 | 10 * n 19 | } else { 20 | // 自动截取 21 | n / 2 22 | }; 23 | assert_eq!(big_n, 6); 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/flowcontrol/index (另一个副本).md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的 while let 表达式" 3 | linkTitle: "while let" 4 | weight: 1670 5 | date: 2021-03-29 6 | description: Rust的 while let 表达式 7 | --- 8 | 9 | while let 可以简化代码,如这个loop: 10 | 11 | ```rust 12 | let mut v = vec![1,2,3,4,5]; 13 | loop { 14 | match v.pop() { 15 | Some(x) => println!("{}", x), 16 | None => break, 17 | } 18 | } 19 | ``` 20 | 21 | 可以改写为: 22 | 23 | ```rust 24 | let mut v = vec![1,2,3,4,5]; 25 | while let Some(x) = v.pop() { 26 | println!("{}", x); 27 | } 28 | ``` 29 | 30 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/flowcontrol/loop.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的loop循环表达式" 3 | linkTitle: "loop" 4 | weight: 1630 5 | date: 2021-03-29 6 | description: Rust的loop循环表达式 7 | --- 8 | 9 | loop 循环,相当于一个 while true,需要程序自己 break: 10 | 11 | ```rust 12 | let mut n = 1; 13 | loop { 14 | if n > 101 { break; } 15 | if n % 15 == 0 { 16 | println!("fizzbuzz"); 17 | } else if n % 3 == 0 { 18 | println!("fizz"); 19 | } else if n % 5 == 0 { 20 | println!("buzz"); 21 | } else { 22 | println!("{}", n); 23 | } 24 | n += 1; 25 | } 26 | ``` 27 | 28 | 强调:**当使用无限循环时,务必使用 loop**,避免使用 while true。 29 | 30 | 31 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/flowcontrol/match.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的match表达式" 3 | linkTitle: "match" 4 | weight: 1650 5 | date: 2021-03-29 6 | description: Rust的match表达式 7 | --- 8 | 9 | 10 | match用于匹配各种情况,类似其他语言的 switch 或 case。 11 | 12 | 在 Rust 语言中,match 分支使用 模式匹配 (pattern matching)技术,match分支: 13 | 14 | - 左边是模式: 15 | - 不同分支可以是不同的模式 16 | - 必须穷尽每一种可能,所以通常最后使用通配符 _ 17 | - 右边是执行代码 18 | - 同样所有分支必须返回同一个值 19 | 20 | ```rust 21 | let number = 42; 22 | match number { 23 | // 模式为单个值 24 | 0 => println!("Origin"), 25 | // 模式为Range 26 | 1...3 => println!("All"), 27 | // 模式为 多个值 28 | | 5 | 7 | 13 => println!("Bad Luck"), 29 | // 绑定模式,将模式中的值绑定给一个变量,供右边执行代码使用 30 | n @ 42 => println!("Answer is {}", n), 31 | // _ 通配符处理剩余情况 32 | _ => println!("Common"), 33 | } 34 | ``` 35 | 36 | match语句可以直接用来赋值,代码比较简练: 37 | 38 | ```rust 39 | let boolean = true; 40 | let binary = match boolean { 41 | false => 0, 42 | true => 1, 43 | }; 44 | ``` 45 | 46 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/flowcontrol/while.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的while循环表达式" 3 | linkTitle: "while" 4 | weight: 1630 5 | date: 2021-03-29 6 | description: Rust的while循环表达式 7 | --- 8 | 9 | while 循环,没啥特别: 10 | 11 | ```rust 12 | let mut n = 1; 13 | while n < 101 { 14 | if n % 15 == 0 { 15 | println!("fizzbuzz"); 16 | } else if n % 3 == 0 { 17 | println!("fizz"); 18 | } else if n % 5 == 0 { 19 | println!("buzz"); 20 | } else { 21 | println!("{}", n); 22 | } 23 | n += 1; 24 | } 25 | ``` 26 | 27 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/grammar.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust语法速查表" 3 | linkTitle: "速查表" 4 | date: 2021-03-29 5 | weight: 1001 6 | description: > 7 | Rust语法速查表 8 | --- 9 | 10 | 语法汇总和速查表。 11 | 12 | ## 基本语法 13 | 14 | ### 类型 15 | 16 | ```rust 17 | let a = 1; // 定义变量,默认不可变 18 | let b: bool = true; // 明确指定变量类型 19 | let mut x = 5; // 定义可变变量 20 | const MAX_POINTS: u32 = 100_000; // 定义常量 21 | let i:i32 = _f as i32; // 转数据类型 22 | type Int = i32; // 用关键字 type 为i32类型创建别名Int 23 | 24 | // Rust 的 never 类型( ! )用于表示永远不可能有返回值的计算类型。 25 | #![feature(never_type)] 26 | let x:! = { 27 | return 123 28 | }; 29 | 30 | // 对整行进行注释 31 | /* .. 对区块注释 */ 32 | /// 生成库文档,一般用于函数或者结构体的说明,置于说明对象的上方 33 | //! 也生成库文档,一般用于说明整个模块的功能,置于模块文件的头部 34 | 35 | let tup: (i32, f64, u8) = (500, 6.4, 1); // 元组(tuple) 36 | let (x, y, z) = tup; // 模式匹配(pattern matching)来解构元组值 37 | (1,) // 当元组中只有一个元素时,需要加逗号,即 38 | `()` // 空元组, 39 | let arr: [i32; 3] = [1, 2, 3]; // 数组 40 | assert_eq!((1..5), Range{ start: 1, end: 5 }); // 范围类型,左闭右开 41 | assert_eq!((1..=5), RangeInclusive::new(1, 5)); // 范围类型,全闭 42 | let arr: [i32; 5] = [1, 2, 3, 4, 5]; // 固定大小数组的切片 43 | let arr = &mut [1, 2, 3]; // 可变数组的切片 44 | let vec = vec![1, 2, 3]; // 使用 vec! 宏定义的动态数组的切片 45 | let str_slice: &[&str] = &["one", "two", "three"]; // 字符串数组的切片 46 | pub struct People { // Named-Field Struct 47 | name: &'static str, 48 | gender: u32, 49 | } // 注意这里没有分号 50 | let alex = People::new("Alex", 1); // 用 :: 来调用new方法,默认不可变 51 | struct Color(i32, i32, i32); // 注意这里要有分号! Tuple-Like Struct,字段没有名字,只有类型 52 | let color = Color(0, 1, 2); // 直接构造,不用new方法 53 | struct Integer(u32); // 当元组结构体只有一个字段的时候,称为 New Type 模式 54 | struct Empty; // 等价于 struct Empty {},单元结构体是没有任何字段的结构体。 55 | 56 | enum Number { // 无参数枚举 57 | Zero, 58 | One, 59 | Two, 60 | } 61 | enum Color { // 类C枚举 62 | Red = 0xff0000, 63 | Green = 0x00ff00, 64 | Blue = 0x0000ff, 65 | } 66 | enum IpAddr { // 带参数枚举 67 | V4(u8, u8, u8, u8), 68 | V6(String), 69 | } 70 | let mut v1 = vec![]; // 用宏创建可变向量 71 | let v2 = vec![0; 10]; // 用宏创建不可变向量 72 | let mut v3 = Vec::new(); // 用 new 方法创建向量 73 | 74 | let a = [1,2,3]; 75 | let b = &a; // 引用操作符 &,不可变,本质上是一种非空指针 76 | let mut c = vec![1,2,3]; // 要获取可变引用,必须先声明可变绑定 77 | let d = &mut c; // 通过 &mut 得到可变引用 78 | 79 | let mut x = 10; 80 | let ptr_x = &mut x as *mut i32; // 可变原始指针 *&mut T 81 | let y = Box::new(20); 82 | let ptr_y = &*y as *const i32; // 不可变原始指针 *const T 83 | 84 | 85 | pub fn math(op: fn(i32, i32) -> i32, a: i32, b: i32) -> i32{ /// 将函数作为参数传递 86 | op(a, b) /// 通过函数指针调用函数 87 | } 88 | fn true_maker() -> fn() -> bool { is_true } /// 函数的返回值是另外一个函数 89 | 90 | let box_point = Box::new(Point { x: 0.0, y: 0.0 }); // 智能指针 91 | 92 | 93 | ``` 94 | 95 | ## 流程处理 96 | 97 | ```rust 98 | let big_n = if n < 10 && n > -10 { // if 不带括号,真不适应 99 | 10 * n 100 | } else { 101 | n / 2 102 | }; 103 | 104 | for n in 1..101 {} // for … in 循环 105 | while n < 101 {} // while 循环 106 | loop { } // loop 循环,相当于一个 while true,需要程序自己 break 107 | 108 | ``` 109 | 110 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/pointer/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的指针" 3 | linkTitle: "指针" 4 | weight: 1500 5 | date: 2021-03-29 6 | description: > 7 | Rust的指针 8 | --- -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/pointer/fn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的函数指针(Fn Pointer)" 3 | linkTitle: "函数指针(Fn Pointer)" 4 | weight: 1530 5 | date: 2021-03-29 6 | description: > 7 | Rust的函数指针(Fn Pointer) 8 | --- 9 | 10 | 函数在Rust中是一等公民,函数自身就可以作为函数的参数和返回值使用。 11 | 12 | ### 函数作为参数 13 | 14 | ```rust 15 | ​``` 16 | /// 将函数作为参数传递 17 | pub fn math(op: fn(i32, i32) -> i32, a: i32, b: i32) -> i32{ 18 | /// 通过函数指针调用函数 19 | op(a, b) 20 | } 21 | fn sum(a: i32, b: i32) -> i32 { 22 | a + b 23 | } 24 | fn product(a: i32, b: i32) -> i32 { 25 | a * b 26 | } 27 | 28 | let a = 2; 29 | let b = 3; 30 | assert_eq!(math(sum, a, b), 5); 31 | assert_eq!(math(product, a, b), 6); 32 | ​``` 33 | ``` 34 | 35 | ### 函数作为返回值 36 | 37 | ```rust 38 | fn is_true() -> bool { true } 39 | /// 函数的返回值是另外一个函数 40 | fn true_maker() -> fn() -> bool { is_true } 41 | /// 通过函数指针调用函数 42 | assert_eq!(true_maker()(), true); 43 | ​``` 44 | ``` 45 | 46 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/pointer/pointer.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的指针概述" 3 | linkTitle: "指针概述" 4 | weight: 1501 5 | date: 2021-03-29 6 | description: > 7 | Rust的指针概述 8 | --- 9 | 10 | Rust 中将可以表示内存地址的类型成为 **指针**。 11 | 12 | Rust提供了多种类型的指针: 13 | 14 | - 引用(Reference) 15 | - 原生指针(Raw Pointer) 16 | - 函数指针(fn Pointer) 17 | - 智能指针(Smart Pointer) 18 | 19 | Rust 可以划分为 Safe Rust 和 Unsafe Rust 两部分。 20 | 21 | ### Safe Rust 22 | 23 | 引用主要应用于 Safe Rust。 24 | 25 | 在Safe Rust 中,编译器会对引用进行借用检查,以保证内存安全和类型安全。 26 | 27 | ### Unsafe Rust 28 | 29 | 原生引用主要用于 Unsafe Rust。 30 | 31 | 原生引用不在 Safe Rust 的控制范围内,需要编程人员自己保证安全。 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/pointer/raw-pointer.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的原始引用(Raw Reference)" 3 | linkTitle: "原始引用(Raw Reference)" 4 | weight: 1520 5 | date: 2021-03-29 6 | description: > 7 | Rust的原始引用(Raw Reference) 8 | --- 9 | 10 | Rust 支持两种原始引用: 11 | 12 | - 不可变原始指针 `*const T` 13 | - 可变原始指针 `*&mut T` 14 | 15 | 用 as 操作符可以将引用转为原始指针: 16 | 17 | ```rust 18 | let mut x = 10; 19 | let ptr_x = &mut x as *mut i32; 20 | let y = Box::new(20); 21 | let ptr_y = &*y as *const i32; 22 | 23 | // 原生指针操作要放在unsafe中执行 24 | unsafe { 25 | *ptr_x += *ptr_y; 26 | } 27 | assert_eq!(x, 30); 28 | ``` 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/pointer/reference.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的引用(Reference)" 3 | linkTitle: "引用(Reference)" 4 | weight: 1510 5 | date: 2021-03-29 6 | description: Rust的引用(Reference) 7 | --- 8 | 9 | Rust 提供引用操作符 `&`,可以直接获取表达式的存储单元地址,即内存地址。 10 | 11 | 引用本质上是一种非空指针。 12 | 13 | ```rust 14 | let a = [1,2,3]; 15 | let b = &a; 16 | println!("{:p}", b); // 0x7ffcbc067704 17 | 18 | // 要获取可变引用,必须先声明可变绑定 19 | let mut c = vec![1,2,3]; 20 | // 通过 &mut 得到可变引用 21 | let d = &mut c; 22 | d.push(4); 23 | println!("{:?}", d); // [1, 2, 3, 4] 24 | 25 | let e = &42; 26 | assert_eq!(42, *e); 27 | ``` 28 | 29 | 30 | 31 | 从语义上说,不管是 `&a` 还是 `&mut c`,都是对原有变量的所有权的借用,所以引用也被称为借用。 32 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/pointer/smart.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的智能指针(Smart Pointer)" 3 | linkTitle: "智能指针(Smart Pointer)" 4 | weight: 1540 5 | date: 2021-03-29 6 | description: > 7 | Rust的智能指针(Smart Pointer) 8 | --- 9 | 10 | 智能指针 (Smart Pointer) 源自c++,Rust 引入后成为 Rust 语言中最重要的一种数据结构。 11 | 12 | ### 功能介绍 13 | 14 | Rust 中的值默认被分配到 栈内存。可以通过 `Box` 将值装箱(在堆内存中分配)。 15 | 16 | - `Box` 是指向类型为T的堆内存分配值的智能指针。 17 | - 当 `Box` 超出作用域范围时,将调用其析构函数,销毁内部对象,并自动释放内存。 18 | - 可以通过解引用操作符来获取`Box`中的T 19 | 20 | `Box` 的行为像引用,并可以自动释放内存,所以称为智能指针。 21 | 22 | ### `Box`类型 23 | 24 | Rust 中提供了很多智能指针类型。 25 | 26 | ```rust 27 | #[derive(Debug, PartialEq)] 28 | struct Point { 29 | x: f64, 30 | y: f64, 31 | } 32 | let box_point = Box::new(Point { x: 0.0, y: 0.0 }); 33 | let unboxed_point: Point = *box_point; 34 | assert_eq!(unboxed_point, Point { x: 0.0, y: 0.0 }); 35 | ``` 36 | 37 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/string/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的字符串" 3 | linkTitle: "字符串" 4 | weight: 1300 5 | date: 2021-03-29 6 | description: > 7 | Rust的字符串 8 | --- 9 | 10 | 出于内存安全的考虑,Rust将字符串分成两种类型: 11 | 12 | 1. str字符串:固定长度,不可改变 13 | 2. String字符串:可变长度 14 | 15 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/string/str.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust中的str字符串" 3 | linkTitle: "str字符串" 4 | date: 2021-03-29 5 | weight: 1310 6 | description: Rust中的str字符串 7 | --- 8 | 9 | Rust的原始字符串类型,也称为 字符串切片。 10 | 11 | 通常以不可变借用的形式存在,既 `&str`。 12 | 13 | str 由两部分组成: 14 | 15 | - 指向字符串序列的指针 16 | - 记录长度的值 17 | 18 | ```rust 19 | use std::slice::from_raw_parts; 20 | use std::str::from_utf8; 21 | 22 | let truth: &'static str = "Rust是一门优雅的语言"; 23 | let ptr = truth.as_ptr(); 24 | let len = truth.len(); 25 | assert_eq!(28, len); 26 | 27 | let s = unsafe { 28 | let slice = from_raw_parts(ptr, len); 29 | from_utf8(slice) 30 | }; 31 | assert_eq!(s, Ok(truth)); 32 | ``` 33 | 34 | Rust 中的字符串本质上是一段有效的 UTF-8 字符序列。 35 | 36 | 37 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/string/string.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust中的string字符串" 3 | linkTitle: "string字符串" 4 | date: 2021-03-29 5 | weight: 1320 6 | description: Rust中的string字符串 7 | --- 8 | 9 | ### 字符串编码 10 | 11 | ```rust 12 | // 将UTF-8序列转为字符串 13 | let tao = std::str::from_utf8(&[0xE9u8, 0x81u8, 0x93u8]).unwrap(); 14 | assert_eq!("道", tao); 15 | 16 | // 将16进制Unicode码位转为字符串 17 | assert_eq!("道", String::from("\u{9053}")); 18 | 19 | let unicode_x = 0x9053; 20 | let utf_x_hex = 0xe98193; 21 | let utf_x_bin = 0b111010011000000110010011; 22 | println!("unicode_x: {:b}", unicode_x); 23 | println!("utf_x_hex: {:b}", utf_x_hex); 24 | println!("utf_x_bin: 0x{:x}", utf_x_bin); 25 | ``` 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/type/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的数据类型" 3 | linkTitle: "数据类型" 4 | weight: 1200 5 | date: 2021-03-29 6 | description: > 7 | Rust的数据类型 8 | --- 9 | 10 | Rust 是 **静态类型**(*statically typed*)语言,在编译时必须知道所有变量的类型。在 Rust 中,每一个值有明确的 **数据类型**(*data type*),以便明确数据处理方式。 11 | 12 | Rust 有两类数据类型子集:标量(scalar)和复合(compound) 13 | 14 | ### 标量类型 15 | 16 | **标量**(*scalar*)类型代表一个单独的值。 17 | 18 | Rust 有四种基本的标量类型: 19 | 20 | 1. 整型(integers) 21 | 2. 浮点型(floating-point numbers) 22 | 3. 布尔类型(Booleans) 23 | 4. 字符(characters) 24 | 25 | ### 复合类型 26 | 27 | **复合类型**(*Compound types*)可以将多个值组合成一个类型。 28 | 29 | Rust 有两个原生的复合类型: 30 | 31 | 1. 元组(tuple) 32 | 2. 数组(array) 33 | 34 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/type/array.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的数组(Array)类型" 3 | linkTitle: "数组(Array)" 4 | date: 2021-03-29 5 | weight: 1270 6 | description: > 7 | Rust的数组(Array)类型 8 | --- 9 | 10 | 数组(array)与元组不同,数组中的每个元素的类型必须相同。数组的特点是: 11 | 12 | - 数组大小固定 13 | - 元素均为相同类型 14 | - 默认不可变 15 | 16 | 可以通过 `let mut` 关键字定义可变绑定的 mut_arr,但是也只能通过下标修改数组元素的值。 17 | 18 | 数组的类型签名为 [T; N]: 19 | 20 | - T 是泛型标记,代表数组中元素的具体类型 21 | - N 是数组长度,是一个 **编译时常量**,必须在编译时确认值,而且不可改变。 22 | 23 | Rust 中数组的定义和使用方式: 24 | 25 | ```rust 26 | // 声明数组,默认不可变 27 | let arr: [i32; 3] = [1, 2, 3]; 28 | // 声明可变数组 29 | let mut mut_arr = [1, 2, 3]; 30 | assert_eq!(1, mut_arr[0]); 31 | // 通过下标修改可变数组元素的值 32 | mut_arr[0] = 3; 33 | assert_eq!(3, mut_arr[0]); 34 | // 创建初始值为0大小为10的数组 35 | let init_arr = [0; 10]; 36 | assert_eq!(0, init_arr[5]); 37 | assert_eq!(10, init_arr.len()); 38 | // 下标越界 39 | // error: index out of bounds: the len is 3 but the index is 5 40 | println!("{:?}", arr[5]); 41 | ``` 42 | 43 | 如果下标越界,rust会以 panic 的方式报错。 44 | 45 | ### 数组内存分配 46 | 47 | 数组是在栈(stack)而不是在堆(heap)上为数据分配内存空间。 48 | 49 | 对于原始固定长度数组,只有实现了 Copy trait 的类型才能作为其元素,也就是说,只有可以在栈上存放的元素才可以存放在该类型的数组中。 50 | 51 | 未来,rust将支持VLA(variable-length array) 数组,即可变长度数组。 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/type/bool.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的布尔型" 3 | linkTitle: "布尔型" 4 | date: 2021-03-29 5 | weight: 1230 6 | description: > 7 | Rust的布尔类型 8 | --- 9 | 10 | Rust 内置布尔类型 11 | 12 | Rust 中的布尔类型使用 `bool` 表示,可以通过as操作将bool转为数字0和1,但是不支持从数字转为bool: 13 | 14 | ```rust 15 | fn main() { 16 | let _t = true; 17 | 18 | // 显式指定类型注解 19 | let _f: bool = false; 20 | 21 | // 用 as 转成 int 22 | let i:i32 = _f as i32; 23 | 24 | print!("{}", i); 25 | } 26 | ``` 27 | 28 | 使用布尔值的主要场景是条件表达式,例如 `if` 表达式。 29 | 30 | ### 标准库 31 | 32 | https://doc.rust-lang.org/std/primitive.bool.html 33 | 34 | bool代表一个值,它只能是true或false。如果你把bool 转为整数,那么true将是1,false将是0。 35 | 36 | bool实现了各种 trait ,如BitAnd、BitOr、Not等,这些特征允许我们使用&、|和 ! 来执行布尔运算。 37 | 38 | assert! 是测试中的一个重要的宏,用于检查一个表达式是否返回真值。 39 | 40 | ```rust 41 | let bool_val = true & false | false; 42 | assert!(!bool_val); 43 | ``` 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/type/char.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的字符型" 3 | linkTitle: "字符型" 4 | date: 2021-03-29 5 | weight: 1240 6 | description: > 7 | Rust的字符类型 8 | --- 9 | 10 | 11 | 使用单引号来定义字符类型。 12 | 13 | Rust 的 `char` 类型代表了一个 Unicode 标量值(Unicode Scalar Value),每个字符占4个字节。 14 | 15 | ```rust 16 | fn main() { 17 | let x = 'r'; 18 | let x = 'Ú'; 19 | // 支持转义 20 | println!("{}", '\''); 21 | println!("{}", '\\'); 22 | println!("{}", '\n'); 23 | println!("{}", '\r'); 24 | println!("{}", '\t'); 25 | // 用 ASCII 码表示字符 26 | assert_eq!('\x2A', '*'); 27 | assert_eq!('\x25', '%'); 28 | // 用 unicode 表示字符 29 | assert_eq!('\u{CA0}', 'ಠ'); 30 | assert_eq!('\u{151}', 'ő'); 31 | // 可以使用 as 操作符将字符转为数字类型 32 | assert_eq!('%' as i8, 37); 33 | assert_eq!('ಠ' as i8, -96); //该字符值的高位会被截断,最终得到-96 34 | } 35 | ``` 36 | 37 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/type/enum.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的枚举(Enum)类型" 3 | linkTitle: "枚举(Enum)" 4 | date: 2021-03-29 5 | weight: 1296 6 | description: > 7 | Rust的枚举(Enum)类型 8 | --- 9 | 10 | 枚举用 enum 关键字定义,有三种类型。 11 | 12 | ### 无参数枚举体 13 | 14 | ```rust 15 | enum Number { 16 | Zero, 17 | One, 18 | Two, 19 | } 20 | let a = Number::One; 21 | match a { 22 | Number::Zero => println!("0"), 23 | Number::One => println!("1"), 24 | Number::Two => println!("2"), 25 | } 26 | ``` 27 | 28 | ### 类C枚举 29 | 30 | ```rust 31 | enum Color { 32 | Red = 0xff0000, 33 | Green = 0x00ff00, 34 | Blue = 0x0000ff, 35 | } 36 | println!("roses are #{:06x}", Color::Red as i32); 37 | println!("violets are #{:06x}", Color::Blue as i32); 38 | ``` 39 | 40 | ### 带参数枚举 41 | 42 | ```rust 43 | enum IpAddr { 44 | V4(u8, u8, u8, u8), 45 | V6(String), 46 | } 47 | let f: fn(u8, u8, u8, u8) -> IpAddr = IpAddr::V4; 48 | let ff: fn(String) -> IpAddr = IpAddr::V6; 49 | let home = IpAddr::V4(127, 0, 0, 1); 50 | ``` 51 | 52 | 带参数枚举的值本质上属于函数指针类型: 53 | 54 | - fn(u8, u8, u8, u8) -> IpAddr 55 | - fn(String) -> IpAddr 56 | 57 | ### 参考资料 58 | 59 | 视频: 60 | 61 | - [Rust Enums Part 1: Introduction](https://www.youtube.com/watch?v=TBixFUJDnRI) 62 | - [Rust Enums part 2: Match & Option](https://www.youtube.com/watch?v=o8bFFwRUEAE) 63 | - [Rust Enums Part 3: if let (Syntax)](https://www.youtube.com/watch?v=sWTu4Lm49Kw) -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/type/float.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的浮点型" 3 | linkTitle: "浮点型" 4 | date: 2021-03-29 5 | weight: 1220 6 | description: > 7 | Rust的浮点类型 8 | --- 9 | 10 | Rust 有两个原生的 **浮点数** `f32` 和 `f64`,分别占 32 位和 64 位。 11 | 12 | 默认类型是 `f64`,因为在现代 CPU 中,它与 `f32` 速度几乎一样,不过精度更高。 13 | 14 | ```rust 15 | let num = 3.1415926f64; 16 | assert_eq!(-3.14, -3.14f64); 17 | assert_eq!(2., 2.0f64); 18 | assert_eq!(2e4, 20000f64); 19 | ``` 20 | 21 | 特殊值: 22 | 23 | ```rust 24 | use std::f32::{INFINITY, NEG_INFINITY, NAN, MIN, MAX}; 25 | println!("{:?}", INFINITY); 26 | println!("{:?}", NEG_INFINITY); 27 | println!("{:?}", NAN); 28 | println!("{:?}", MIN); 29 | println!("{:?}", MAX); 30 | ``` 31 | 打印结果为: 32 | 33 | ```bash 34 | inf 35 | -inf 36 | NaN 37 | -340282350000000000000000000000000000000.0 38 | 340282350000000000000000000000000000000.0 39 | ``` 40 | 41 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/type/integer.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的整型类型" 3 | linkTitle: "整型" 4 | date: 2021-03-29 5 | weight: 1210 6 | description: > 7 | Rust的整型类型 8 | --- 9 | 10 | ### Rust 中的整型 11 | 12 | Rust 内建的整数类型。在有符号列和无符号列中的每一个变体(例如,`i16`)都可以用来声明整数值的类型。 13 | 14 | | 长度 | 有符号 | 无符号 | 15 | | ------ | ------- | ------- | 16 | | 8-bit | `i8` | `u8` | 17 | | 16-bit | `i16` | `u16` | 18 | | 32-bit | `i32` | `u32` | 19 | | 64-bit | `i64` | `u64` | 20 | | arch | `isize` | `usize` | 21 | 22 | 注意:`isize` 和 `usize` 类型依赖运行程序的计算机架构:64 位架构上它们是 64 位的, 32 位架构上它们是 32 位的。 23 | 24 | ### 整型字面值 25 | 26 | 可以使用表格中的任何一种形式编写数字字面值。注意除 byte 以外的所有数字字面值允许使用类型后缀,例如 `57u8`,同时也允许使用 `_` 做为分隔符以方便读数,例如`1_000`。 27 | 28 | | 数字字面值 | 例子 | 说明 | 29 | | ---------------- | ------------- | ---------- | 30 | | Decimal | `98_222` | | 31 | | Hex | `0xff` | 16进制 | 32 | | Octal | `0o77` | 8进制 | 33 | | Binary | `0b1111_0000` | 2进制 | 34 | | Byte (`u8` only) | `b'A'` | 字节字面量 | 35 | 36 | 那么该使用哪种类型的数字呢?如果拿不定主意,Rust 的默认类型通常就很好,数字类型默认是 `i32`:它通常是最快的,甚至在 64 位系统上也是。`isize` 或 `usize` 主要作为某些集合的索引。 37 | 38 | ### 整型溢出 39 | 40 | “整型溢出”(“integer overflow” )在 Rust 中有一些有趣的规则: 41 | 42 | - 当在 debug 模式编译时,Rust 检查这类问题并使程序 *panic* 43 | - 在 release 构建中,Rust 不检测溢出,相反会进行一种被称为 “two’s complement wrapping” 的操作。 44 | 45 | 简而言之,`256` 变成 `0`,`257` 变成 `1`,依此类推。 46 | 47 | 依赖溢出被认为是一种错误,即便可能出现这种行为。如果你确实需要这种行为,标准库中有一个类型显式提供此功能,`Wrapping`。 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/type/never.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的never类型" 3 | linkTitle: "never类型" 4 | date: 2021-03-29 5 | weight: 1250 6 | description: > 7 | Rust的never类型 8 | --- 9 | 10 | Rust 的 never 类型( `!` )用于表示永远不可能有返回值的计算类型。 11 | 12 | Rust 是一个类型安全的语言,所以需要将没有返回值的情况(如线程退出)纳入类型管理。 13 | 14 | ```rust 15 | #![feature(never_type)] 16 | let x:! = { 17 | return 123 18 | }; 19 | ``` 20 | 21 | 报错: 22 | 23 | ```bash 24 | error[E0554]: #![feature] may not be used on the stable release channel 25 | --> src/main.rs:1:1 26 | | 27 | 1 | #![feature(never_type)] 28 | | ^^^^^^^^^^^^^^^^^^^^^^^ 29 | ``` 30 | 31 | never 是试验特性,需要使用 nightly 版本。 -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/type/range.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的范围(Range)类型" 3 | linkTitle: "范围(Range)" 4 | date: 2021-03-29 5 | weight: 1280 6 | description: > 7 | Rust的范围(Range)类型 8 | --- 9 | 10 | Rust 内置的范围类型,包括 左闭右开 和 全币 两种区间,分别是 std::ops::Range 和 std::ops::RangeInclusive 的实例: 11 | 12 | ```rust 13 | // (1..5)是结构体std::ops::Range的一个实例 14 | use std::ops::{Range, RangeInclusive}; 15 | assert_eq!((1..5), Range{ start: 1, end: 5 }); 16 | // (1..=5)是结构体std::ops::RangeInclusive的一个实例 17 | assert_eq!((1..=5), RangeInclusive::new(1, 5)); 18 | // 自带的 sum 方法用于求和 19 | assert_eq!(3+4+5, (3..6).sum()); 20 | assert_eq!(3+4+5+6, (3..=6).sum()); 21 | (3..6) 22 | 23 | // 每个范围都是一个迭代器,可用for 循环打印范围内的元素 24 | for i in (1..5) { 25 | println!("{}", i); 26 | } 27 | for i in (1..=5) { 28 | println!("{}", i); 29 | } 30 | ``` 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/type/slice.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的切片(Slice)类型" 3 | linkTitle: "切片(Slice)" 4 | date: 2021-03-29 5 | weight: 1290 6 | description: > 7 | Rust的切片(Slice)类型 8 | --- 9 | 10 | 11 | Slice 切片是对一个数组(包括固定大小数组和动态数组)的引用片段,可以安全访问数组的一部分,而不需要拷贝。 12 | 13 | 在底层,切片表示为一个指向数组起始位置的指针和数组长度。 14 | 15 | ```rust 16 | // 固定大小数组的切片 17 | let arr: [i32; 5] = [1, 2, 3, 4, 5]; 18 | assert_eq!(&arr, &[1,2,3,4,5]); 19 | assert_eq!(&arr[1..], [2,3,4,5]); 20 | assert_eq!((&arr).len(), 5); 21 | assert_eq!((&arr).is_empty(), false); 22 | 23 | // 可变数组的切片 24 | let arr = &mut [1, 2, 3]; 25 | arr[1] = 7; 26 | assert_eq!(arr, &[1, 7, 3]); 27 | 28 | //使用 vec! 宏定义的动态数组的切片 29 | let vec = vec![1, 2, 3]; 30 | assert_eq!(&vec[..], [1,2,3]); 31 | 32 | // 字符串数组的切片 33 | let str_slice: &[&str] = &["one", "two", "three"]; 34 | assert_eq!(str_slice, ["one", "two", "three"]); 35 | ``` 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/type/struct.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的结构体(Struct)类型" 3 | linkTitle: "结构体(Struct)" 4 | date: 2021-03-29 5 | weight: 1293 6 | description: > 7 | Rust的结构体(Struct)类型 8 | --- 9 | 10 | Rust 提供三种结构体: 11 | 12 | - Named-Field Struct 13 | - Tuple-Like Struct 14 | - Unit-Like Struct 15 | 16 | ### Named-Field Struct 17 | 18 | Named-Field 是最常见的。 19 | 20 | ```rust 21 | #[derive(Debug, PartialEq)] 22 | pub struct People { 23 | name: &'static str, 24 | gender: u32, 25 | } // 注意这里没有分号 26 | 27 | impl People { 28 | // new 方法的参数并没有 &self 29 | fn new(name: &'static str, gender: u32) -> Self { 30 | return People { name: name, gender: gender }; 31 | } 32 | // 读方法,传递的是 &self 不可变引用 33 | fn name(&self) { 34 | println!("name: {:?}", self.name); 35 | } 36 | // 写方法,传递的是 &mut self 可变引用 37 | fn set_name(&mut self, name: &'static str) { 38 | self.name = name; 39 | } 40 | fn gender(&self) { 41 | let gender = if self.gender == 1 { "boy" } else { "girl" }; 42 | println!("gender: {:?}", gender); 43 | } 44 | } 45 | 46 | fn main() { 47 | // 用 :: 来调用new方法,默认不可变 48 | let alex = People::new("Alex", 1); 49 | // 调用其他方法用 . 号,不用传递 &self 50 | // 为啥不直接把 &self 改成类型java的this语法呢?反正也不传递 51 | alex.name(); 52 | alex.gender(); 53 | // 也可以直接构建结构体,绕过new方法 54 | assert_eq!(alex, People { name: "Alex", gender: 1 }); 55 | 56 | // 创建可变结构体 57 | let mut alice = People::new("Alice", 0); 58 | alice.name(); 59 | alice.gender(); 60 | assert_eq!(alice, People { name: "Alice", gender: 0 }); 61 | // 就可以调用set方法了 62 | alice.set_name("Rose"); 63 | alice.name(); 64 | assert_eq!(alice, People { name: "Rose", gender: 0 }); 65 | } 66 | ``` 67 | 68 | 结构体名字要用驼峰法。 69 | 70 | ### Tuple-Like Struct 71 | 72 | 元组结构体像元组和结构体的混合体:字段没有名字,只有类型: 73 | 74 | ```rust 75 | #[derive(Debug, PartialEq)] 76 | struct Color(i32, i32, i32); // 注意这里要有分号! 77 | 78 | fn main() { 79 | // 直接构造,不用new方法 80 | let color = Color(0, 1, 2); 81 | assert_eq!(color.0, 0); 82 | assert_eq!(color.1, 1); 83 | assert_eq!(color.2, 2); 84 | } 85 | ``` 86 | 87 | 使用 `.` 号按下标访问字段。 88 | 89 | 当元组结构体只有一个字段的时候,称为 New Type 模式: 90 | 91 | ```rust 92 | #[derive(Debug, PartialEq)] 93 | struct Integer(u32); 94 | 95 | // 用关键字 type 为i32类型创建别名Int 96 | type Int = i32; 97 | 98 | fn main() { 99 | let int = Integer(10); 100 | assert_eq!(int.0, 10); 101 | 102 | let int: Int = 10; 103 | assert_eq!(int, 10); 104 | } 105 | ``` 106 | 107 | 108 | 109 | ### Unit-Like Struct 110 | 111 | 单元结构体是没有任何字段的结构体。 112 | 113 | ```rust 114 | // 等价于 struct Empty {} 115 | struct Empty; 116 | let x = Empty; 117 | println!("{:p}", &x); 118 | let y = x; 119 | println!("{:p}", &y as *const _); 120 | let z = Empty; 121 | println!("{:p}", &z as *const _); 122 | 123 | // struct RangeFull; // 标准库源码中RangeFull就是一个单元结构体 124 | assert_eq!((..), std::ops::RangeFull); // RangeFull就是(..),表示全范围 125 | ``` 126 | 127 | 单元结构体和 new type 模式类似,也相当于定义了一个新的类型。 128 | 129 | 单元结构体一般用于特定场景,标准库源码中RangeFull就是一个单元结构体。 130 | 131 | ### 参考资料 132 | 133 | 视频: 134 | 135 | - [Rust: Structs](https://www.youtube.com/watch?v=jE-nqgIoN9o) 136 | - [Rust Structs by Example Part 1](https://www.youtube.com/watch?v=WZYnqJ37QcI) 137 | - [Rust Structs by Example Part 2](https://www.youtube.com/watch?v=tEg0PlC7Fqs) 138 | 139 | -------------------------------------------------------------------------------- /content/zh-cn/docs/grammar/type/tuple.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的元组(Tuple)类型" 3 | linkTitle: "元组(Tuple)" 4 | date: 2021-03-29 5 | weight: 1260 6 | description: > 7 | Rust的元组(Tuple)类型 8 | --- 9 | 10 | 元组(tuple)是一种异构有限序列: 11 | 12 | - **异构** 指元组内的元素可以是不同的类型 13 | - **有限** 是指元组有固定长度 14 | 15 | ### 创建元组 16 | 17 | 使用包含在圆括号中的逗号分隔的值列表来创建一个元组。元组中的每一个位置都有一个类型,而且这些不同值的类型也不必是相同的: 18 | 19 | ```rust 20 | fn main() { 21 | let tup: (i32, f64, u8) = (500, 6.4, 1); 22 | } 23 | ``` 24 | 25 | `tup` 变量绑定到整个元组上,因为元组是一个单独的复合元素。 26 | 27 | ### 元组取值 28 | 29 | 为了从元组中获取单个值,可以使用模式匹配(pattern matching)来解构元组值: 30 | 31 | ```rust 32 | fn main() { 33 | let tup = (500, 6.4, 1); 34 | 35 | let (x, y, z) = tup; 36 | 37 | println!("The value of y is: {}", y); 38 | } 39 | ``` 40 | 41 | 除了使用模式匹配解构外,也可以使用点号(`.`)后跟值的索引来直接访问它们: 42 | 43 | ```rust 44 | fn main() { 45 | let x: (i32, f64, u8) = (500, 6.4, 1); 46 | 47 | let five_hundred = x.0; 48 | 49 | let six_point_four = x.1; 50 | 51 | let one = x.2; 52 | } 53 | ``` 54 | 55 | 跟大多数编程语言一样,元组的第一个索引值是 0。 56 | 57 | ### 特殊元组 58 | 59 | 当元组中只有一个元素时,需要加逗号,即 `(1,)` 60 | 61 | 空元组,`()` -------------------------------------------------------------------------------- /content/zh-cn/docs/installation/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust安装" 3 | linkTitle: "安装" 4 | weight: 200 5 | date: 2021-03-29 6 | description: > 7 | 在各个操作系统上安装Rust 8 | --- 9 | 10 | Rust安装方式参考官方地址: https://www.rust-lang.org/en-US/install.html 11 | 12 | -------------------------------------------------------------------------------- /content/zh-cn/docs/installation/cargo/images/cargo-proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/content/zh-cn/docs/installation/cargo/images/cargo-proxy.png -------------------------------------------------------------------------------- /content/zh-cn/docs/installation/cargo/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "cargo 设置" 3 | linkTitle: "cargo" 4 | date: 2025-04-09 5 | weight: 40 6 | description: > 7 | 为 Rust 配置 cargo 8 | --- 9 | 10 | 为了加速 cargo 的构建,最好配置 cargo 的源为国内的源,或者使用 nexus 的代理源。 11 | 12 | ## 使用国内源 13 | 14 | ```bash 15 | vi ~/.cargo/config 16 | ``` 17 | 18 | 打开(或创建)配置文件 `.cargo/config`,加入以下内容: 19 | 20 | ```properties 21 | [source.crates-io] 22 | # 指定使用下面哪个源,修改为source.后面的内容即可 23 | replace-with = 'ustc' 24 | 25 | #阿里云 26 | [source.aliyun] 27 | registry = "sparse+https://mirrors.aliyun.com/crates.io-index/" 28 | 29 | # 中国科学技术大学 30 | [source.ustc] 31 | registry = "https://mirrors.ustc.edu.cn/crates.io-index" 32 | 33 | # 上海交通大学 34 | [source.sjtu] 35 | registry = "https://mirrors.sjtug.sjtu.edu.cn/git/crates.io-index/" 36 | 37 | # 清华大学 38 | [source.tuna] 39 | registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git" 40 | 41 | # rustcc社区 42 | [source.rustcc] 43 | registry = "https://code.aliyun.com/rustcc/crates.io-index.git" 44 | ``` 45 | 46 | 参考: 47 | 48 | - [rust - How do I debug `cargo build` hanging at "Updating crates.io index"? - Stack Overflow](https://stackoverflow.com/questions/53361052/how-do-i-debug-cargo-build-hanging-at-updating-crates-io-index) 49 | 50 | - [cargo 使用国内源加速构建](https://www.cnblogs.com/trigger-cn/p/18334279) 51 | 52 | ## 使用 nexus 代理源 53 | 54 | nexus 支持 cargo 的代理, 具体可以参考: 55 | 56 | - [Nexus 3 Rust Cargo Support](https://help.sonatype.com/en/rust-cargo.html) 57 | 58 | 但这个文档实在太过简陋, 很多地方没有说清楚, 所以这里详细说明下。 59 | 60 | ### 配置 nexus 代理源 61 | 62 | 在 nexus 下创建一个 cargo proxy 代理仓库,用于官方仓库: 63 | 64 | - cargo-proxy-cratesio: https://index.crates.io 65 | 66 | > 注意: 只能代理官方仓库 `cargo-proxy-cratesio`, 不能代理国内的源,下面有说明。 67 | 68 | 再创建一个 cargo hosted 仓库 69 | 70 | - cargo-private 71 | 72 | 最后再创建一个 cargo group 仓库, 名为 `cargo-public`, 将上面两个仓库添加进去,顺序为: 73 | 74 | - cargo-private 75 | - cargo-proxy-cratesio 76 | 77 | ### 配置 cargo 使用 nexus 代理源 78 | 79 | ```bash 80 | vi ~/.cargo/config 81 | ``` 82 | 83 | 打开(或创建)配置文件 `.cargo/config.toml`,加入以下内容: 84 | 85 | ```properties 86 | [registries.nexus] 87 | index = "sparse+http://192.168.3.91:8081/repository/cargo-public/" 88 | 89 | [registry] 90 | default = "nexus" 91 | 92 | [source.crates-io] 93 | replace-with = "nexus" 94 | 95 | [source.nexus] 96 | registry = "sparse+http://192.168.3.91:8081/repository/cargo-public/" 97 | ``` 98 | 99 | 参考: 100 | 101 | - [Nexus proxy repository for Cargo/Rust](https://gist.github.com/mashintsev/3e6ab7840d6233ab7932565d056b8158) 102 | 103 | ## 现有问题 104 | 105 | ### 不能代理国内源 106 | 107 | 但这里有个问题,就是 cargo proxy 仓库只能代理官方仓库 https://index.crates.io, 而不能代理国内的源, 108 | 109 | 会报错: 110 | 111 | ```bash 112 | warning: spurious network error (2 tries remaining): failed to get successful HTTP response from `http://192.168.3.91:8081/repository/cargo-proxy-ustc/crates/async-recursion/1.1.1/download` (192.168.0.246), got 500 113 | body: 114 | ``` 115 | 116 | 暂时没有找到解决办法, 所以只能使用官方仓库作为 cargo proxy 仓库的上游源头。 117 | 118 | ### cargo hosted 和 cargo group 仓库报错 119 | 120 | cargo hosted 和 cargo group 仓库在创建后报错, 具体报错信息如下: 121 | 122 | ```bash 123 | 400 bad request 124 | ``` 125 | 126 | 这个事情比较诡异,因为我第一次操作时,功能都正常。但是,我之后把测试用的那台虚拟机删除,再正式创建时,就怎么都报错 400 bad request。用了很长时间排查也未来找到原因。 127 | 128 | 最后, 暂时只能重新创建 cargo proxy 仓库, 重新配置 cargo 使用 cargo proxy 仓库, 先不使用 cargo hosted 和 cargo group 仓库。 129 | 130 | ## 验证构建 131 | 132 | ### 验证 cargo proxy 仓库 133 | 134 | 尝试构建 linkerd2-proxy, 验证是否能正常构建: 135 | 136 | ```bash 137 | mkdir -p ~/work/code/temp/rust-demo 138 | cd ~/work/code/temp/rust-demo 139 | 140 | git clone https://github.com/linkerd/linkerd2-proxy.git 141 | cd linkerd2-proxy 142 | 143 | # 确保安装了以下依赖 144 | sudo apt install -y cmake make gcc g++ 145 | sudo apt install -y clang libclang-dev 146 | 147 | # 设置环境变量 148 | export RUSTFLAGS="--cfg tokio_unstable" 149 | 150 | # 构建 151 | cargo build 152 | ``` 153 | 154 | 代理成功之后, 下载 cargo crates 的速度会非常快, cargo 代理仓库的内容如下图所示: 155 | 156 | ![](images/cargo-proxy.png) 157 | 158 | #### 清理 cache 和 index 159 | 160 | 为了多次验证, 需要清理 cache 和 index: 161 | 162 | ```bash 163 | # 第一次运行时需要安装 cargo-cache 164 | cargo install cargo-cache 165 | 166 | # 清理 cache 和 index 167 | cargo cache -a 168 | 169 | # 清理 registry 索引 170 | rm -rf ~/.cargo/registry/index/* 171 | 172 | # 清理 git 索引 173 | rm -rf ~/.cargo/git/* 174 | 175 | # 清理 build 缓存 176 | cargo clean 177 | ``` 178 | 179 | 遇到特殊情况,可以考虑重置 cargo 的配置: 180 | 181 | ```bash 182 | rm -rf ~/.cargo/ 183 | # 重新安装 rust 184 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 185 | 186 | # 重新初始化 Cargo 187 | rustup update 188 | ``` 189 | 190 | ### 验证 cargo hosted 仓库 191 | 192 | 验证 cargo hosted 仓库是否能正常构建: 193 | 194 | ```bash 195 | cargo publish 196 | ``` 197 | 198 | TODO:稍后再验证吧,好像一般也很少需要使用 cargo hosted 仓库。 199 | 200 | 201 | 202 | 203 | -------------------------------------------------------------------------------- /content/zh-cn/docs/installation/linux/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Linux 安装" 3 | linkTitle: "Linux" 4 | date: 2025-04-09 5 | weight: 10 6 | description: > 7 | 在 Linux 上安装 Rust 8 | --- 9 | 10 | ### 安装 11 | 12 | 执行命令: 13 | 14 | ```bash 15 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 16 | ``` 17 | 18 | 然后依照屏幕提示: 19 | 20 | ```bash 21 | info: downloading installer 22 | 23 | Welcome to Rust! 24 | 25 | This will download and install the official compiler for the Rust 26 | programming language, and its package manager, Cargo. 27 | 28 | Rustup metadata and toolchains will be installed into the Rustup 29 | home directory, located at: 30 | 31 | /home/sky/.rustup 32 | 33 | This can be modified with the RUSTUP_HOME environment variable. 34 | 35 | The Cargo home directory is located at: 36 | 37 | /home/sky/.cargo 38 | 39 | This can be modified with the CARGO_HOME environment variable. 40 | 41 | The cargo, rustc, rustup and other commands will be added to 42 | Cargo's bin directory, located at: 43 | 44 | /home/sky/.cargo/bin 45 | 46 | This path will then be added to your PATH environment variable by 47 | modifying the profile files located at: 48 | 49 | /home/sky/.profile 50 | /home/sky/.bashrc 51 | /home/sky/.zshenv 52 | 53 | You can uninstall at any time with rustup self uninstall and 54 | these changes will be reverted. 55 | 56 | Current installation options: 57 | 58 | 59 | default host triple: x86_64-unknown-linux-gnu 60 | default toolchain: stable (default) 61 | profile: default 62 | modify PATH variable: yes 63 | 64 | 1) Proceed with standard installation (default - just press enter) 65 | 2) Customize installation 66 | 3) Cancel installation 67 | > 68 | ``` 69 | 70 | 这里选择1默认模式,继续: 71 | 72 | ```bash 73 | info: profile set to 'default' 74 | info: default host triple is x86_64-unknown-linux-gnu 75 | info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu' 76 | info: latest update on 2025-04-03, rust version 1.86.0 (05f9846f8 2025-03-31) 77 | info: downloading component 'cargo' 78 | info: downloading component 'clippy' 79 | info: downloading component 'rust-docs' 80 | info: downloading component 'rust-std' 81 | info: downloading component 'rustc' 82 | 72.8 MiB / 72.8 MiB (100 %) 31.1 MiB/s in 1s 83 | info: downloading component 'rustfmt' 84 | info: installing component 'cargo' 85 | info: installing component 'clippy' 86 | info: installing component 'rust-docs' 87 | 21.2 MiB / 21.2 MiB (100 %) 10.2 MiB/s in 2s 88 | info: installing component 'rust-std' 89 | 27.1 MiB / 27.1 MiB (100 %) 11.6 MiB/s in 2s 90 | info: installing component 'rustc' 91 | 72.8 MiB / 72.8 MiB (100 %) 13.1 MiB/s in 5s 92 | info: installing component 'rustfmt' 93 | info: default toolchain set to 'stable-x86_64-unknown-linux-gnu' 94 | 95 | stable-x86_64-unknown-linux-gnu installed - rustc 1.86.0 (05f9846f8 2025-03-31) 96 | 97 | 98 | Rust is installed now. Great! 99 | 100 | To get started you may need to restart your current shell. 101 | This would reload your PATH environment variable to include 102 | Cargo's bin directory ($HOME/.cargo/bin). 103 | 104 | To configure your current shell, you need to source 105 | the corresponding env file under $HOME/.cargo. 106 | 107 | This is usually done by running one of the following (note the leading DOT): 108 | . "$HOME/.cargo/env" # For sh/bash/zsh/ash/dash/pdksh 109 | source "$HOME/.cargo/env.fish" # For fish 110 | source "$HOME/.cargo/env.nu" # For nushell 111 | ``` 112 | 113 | ```bash 114 | vi ~/.zshrc 115 | ``` 116 | 117 | 在文件末尾加入: 118 | 119 | ```bash 120 | # rust 121 | . "$HOME/.cargo/env" 122 | ``` 123 | 124 | 保存退出, 重新登录, 或者执行命令: 125 | 126 | ```bash 127 | source $HOME/.cargo/env 128 | ``` 129 | 130 | 验证安装: 131 | 132 | ```bash 133 | $ rustc --version 134 | rustc 1.86.0 (05f9846f8 2025-03-31) 135 | ``` 136 | 137 | ### 配置cargo 138 | 139 | 打开(或创建)文件 `~/.cargo/config`,加入以下内容: 140 | 141 | ```properties 142 | [source.crates-io] 143 | registry = "https://github.com/rust-lang/crates.io-index" 144 | replace-with = 'ustc' 145 | 146 | [source.ustc] 147 | registry = "git://mirrors.ustc.edu.cn/crates.io-index" 148 | ``` 149 | 150 | 参考: 151 | 152 | - [rust - How do I debug `cargo build` hanging at "Updating crates.io index"? - Stack Overflow](https://stackoverflow.com/questions/53361052/how-do-i-debug-cargo-build-hanging-at-updating-crates-io-index) -------------------------------------------------------------------------------- /content/zh-cn/docs/installation/upgrade/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust 版本升级" 3 | linkTitle: "版本升级" 4 | date: 2025-04-09 5 | weight: 30 6 | description: > 7 | 升级 Rust 的版本 8 | --- 9 | 10 | ### 官方方式 11 | 12 | 通过 `rustup` 安装了 Rust 之后,更新到最新版本只要运行如下更新脚本: 13 | 14 | ``` 15 | $ rustup update 16 | ``` 17 | 18 | 尝试在mac下从 1.40 升级到 1.42 成功,输出如下: 19 | 20 | ```bash 21 | $ rustup update 22 | info: syncing channel updates for 'stable-x86_64-apple-darwin' 23 | 463.3 KiB / 463.3 KiB (100 %) 414.2 KiB/s in 1s ETA: 0s 24 | info: latest update on 2020-03-12, rust version 1.42.0 (b8cedc004 2020-03-09) 25 | info: downloading component 'rust-src' 26 | 2.2 MiB / 2.2 MiB (100 %) 313.6 KiB/s in 8s ETA: 0s 27 | info: downloading component 'cargo' 28 | 3.7 MiB / 3.7 MiB (100 %) 321.3 KiB/s in 14s ETA: 0s 29 | info: downloading component 'clippy' 30 | 1.3 MiB / 1.3 MiB (100 %) 327.7 KiB/s in 5s ETA: 0s 31 | info: downloading component 'rust-docs' 32 | 12.1 MiB / 12.1 MiB (100 %) 323.2 KiB/s in 43s ETA: 0s 33 | info: downloading component 'rust-std' 34 | 16.1 MiB / 16.1 MiB (100 %) 345.6 KiB/s in 1m 3s ETA: 0s 35 | info: downloading component 'rustc' 36 | 54.5 MiB / 54.5 MiB (100 %) 342.4 KiB/s in 4m 20s ETA: 0s 37 | info: downloading component 'rustfmt' 38 | 1.9 MiB / 1.9 MiB (100 %) 288.0 KiB/s in 7s ETA: 0s 39 | info: removing previous version of component 'rust-src' 40 | info: removing previous version of component 'cargo' 41 | info: removing previous version of component 'clippy' 42 | info: removing previous version of component 'rust-docs' 43 | info: removing previous version of component 'rust-std' 44 | info: removing previous version of component 'rustc' 45 | info: removing previous version of component 'rustfmt' 46 | info: installing component 'rust-src' 47 | info: installing component 'cargo' 48 | info: installing component 'clippy' 49 | info: installing component 'rust-docs' 50 | 12.1 MiB / 12.1 MiB (100 %) 8.6 MiB/s in 1s ETA: 0s 51 | info: installing component 'rust-std' 52 | info: installing component 'rustc' 53 | 54.5 MiB / 54.5 MiB (100 %) 18.3 MiB/s in 3s ETA: 0s 54 | info: installing component 'rustfmt' 55 | info: checking for self-updates 56 | 57 | stable-x86_64-apple-darwin updated - rustc 1.42.0 (b8cedc004 2020-03-09) (from rustc 1.40.0 (73528e339 2019-12-16)) 58 | 59 | info: cleaning up downloads & tmp directories 60 | ``` 61 | 62 | 尝试在linux 下从 1.54.0 升级到 1.55.0 成功,输出如下: 63 | 64 | ```bash 65 | ➜ ~ rustup update 66 | info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu' 67 | 68 | 679.5 KiB / 679.5 KiB (100 %) 463.5 KiB/s in 1s ETA: 0s 69 | info: latest update on 2021-09-09, rust version 1.55.0 (c8dfcfe04 2021-09-06) 70 | info: downloading component 'rust-src' 71 | info: downloading component 'cargo' 72 | 6.1 MiB / 6.1 MiB (100 %) 4.4 MiB/s in 1s ETA: 0s 73 | info: downloading component 'clippy' 74 | info: downloading component 'rust-docs' 75 | 17.0 MiB / 17.0 MiB (100 %) 4.5 MiB/s in 3s ETA: 0s 76 | info: downloading component 'rust-std' 77 | 22.3 MiB / 22.3 MiB (100 %) 4.6 MiB/s in 5s ETA: 0s 78 | info: downloading component 'rustc' 79 | 51.0 MiB / 51.0 MiB (100 %) 4.2 MiB/s in 11s ETA: 0s 80 | info: downloading component 'rustfmt' 81 | info: removing previous version of component 'rust-src' 82 | info: removing previous version of component 'cargo' 83 | info: removing previous version of component 'clippy' 84 | info: removing previous version of component 'rust-docs' 85 | info: removing previous version of component 'rust-std' 86 | info: removing previous version of component 'rustc' 87 | info: removing previous version of component 'rustfmt' 88 | info: installing component 'rust-src' 89 | info: installing component 'cargo' 90 | info: installing component 'clippy' 91 | info: installing component 'rust-docs' 92 | 17.0 MiB / 17.0 MiB (100 %) 11.3 MiB/s in 1s ETA: 0s 93 | info: installing component 'rust-std' 94 | 22.3 MiB / 22.3 MiB (100 %) 16.7 MiB/s in 1s ETA: 0s 95 | info: installing component 'rustc' 96 | 51.0 MiB / 51.0 MiB (100 %) 18.9 MiB/s in 2s ETA: 0s 97 | info: installing component 'rustfmt' 98 | info: checking for self-updates 99 | 100 | stable-x86_64-unknown-linux-gnu updated - rustc 1.55.0 (c8dfcfe04 2021-09-06) (from rustc 1.54.0 (a178d0322 2021-07-26)) 101 | 102 | info: cleaning up downloads & tmp directories 103 | ``` 104 | 105 | 如果要卸载 Rust 和 `rustup`,运行如下卸载脚本: 106 | 107 | ``` 108 | $ rustup self uninstall 109 | ``` 110 | 111 | ### 归档内容:曾经遇到的升级问题 112 | 113 | 尝试过升级已经安装的rust/cargo,试图从1.22.1升级到1.23,发现重新运行rustup脚本,虽然报告说安装成功,但是实际不会安装新的版本。 114 | 115 | 暂时没有找到升级的方法,只好用最笨的办法,先删除再全新安装: 116 | 117 | ```bash 118 | cd 119 | rm -rf .cargo/ .rustup/ 120 | ``` 121 | 122 | 这个方式理所当然的很不好,原有的所有内容都要重头来一次。 123 | 124 | 后面似乎没有再遇到类似问题。 125 | 126 | -------------------------------------------------------------------------------- /content/zh-cn/docs/installation/windows/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Windows 安装" 3 | linkTitle: "Windows" 4 | date: 2025-04-09 5 | weight: 20 6 | description: > 7 | 在 Windows 上安装 Rust 8 | --- 9 | 10 | ### 安装vs2015 11 | 12 | TBD: 下次验证,参考 https://rustlang-cn.org/office/rust/book/getting-started/ch01-01-installation.html 13 | 14 | 在安装rust之前,windows平台上需要先安装 Microsoft C++ build tools,推荐2015版本。如果不安装,后面在编译时,会报错说"link.exe"无法找到。 15 | 16 | ```bash 17 | note: the msvc targets depend on the msvc linker but `link.exe` was not found 18 | 19 | note: please ensure that VS 2013 or VS 2015 was installed with the Visual C++ option 20 | 21 | error: aborting due to previous error 22 | 23 | error: Could not compile `ws2_32-sys` 24 | ``` 25 | 26 | 打开下面的网站: 27 | 28 | http://landinghub.visualstudio.com/visual-cpp-build-tools 29 | 30 | 选择"Download Visual C++ Build Tools 2015"。 31 | 32 | 下载之后按照提示一路安装即可。 33 | 34 | ### windows安装rust 35 | 36 | 操作系统为windows 10 64位。 37 | 38 | 下载rustup.init.exe,然后安装,按照指示操作,中间要下载rustc等安装文件。 39 | 40 | ```bash 41 | Rust Visual C++ prerequisites 42 | 43 | If you will be targeting the GNU ABI or otherwise know what you are doing then 44 | it is fine to continue installation without the build tools, but otherwise, 45 | install the C++ build tools before proceeding. 46 | 47 | Continue? (Y/n) y 48 | 49 | 50 | Welcome to Rust! 51 | 52 | This will download and install the official compiler for the Rust programming 53 | language, and its package manager, Cargo. 54 | 55 | It will add the cargo, rustc, rustup and other commands to Cargo's bin 56 | directory, located at: 57 | 58 | C:\Users\aoxia\.cargo\bin 59 | 60 | This path will then be added to your PATH environment variable by modifying the 61 | HKEY_CURRENT_USER/Environment/PATH registry key. 62 | 63 | You can uninstall at any time with rustup self uninstall and these changes will 64 | be reverted. 65 | 66 | Current installation options: 67 | 68 | default host triple: x86_64-pc-windows-msvc 69 | default toolchain: stable 70 | modify PATH variable: yes 71 | 72 | 1) Proceed with installation (default) 73 | 2) Customize installation 74 | 3) Cancel installation 75 | 76 | 77 | info: updating existing rustup installation 78 | 79 | 80 | Rust is installed now. Great! 81 | 82 | To get started you need Cargo's bin directory (%USERPROFILE%\.cargo\bin) in 83 | your PATH environment variable. Future applications will automatically have the 84 | correct environment, but you may need to restart your current shell. 85 | 86 | Press the Enter key to continue. 87 | ``` 88 | 89 | 将 `%USERPROFILE%\.cargo\bin` 加入到PATH环境变量中。 90 | 91 | 验证安装,执行`rustc --version`: 92 | 93 | ```bash 94 | $> rustc --version 95 | rustc 1.33.0 (2aa4c46cf 2019-02-28) 96 | ``` -------------------------------------------------------------------------------- /content/zh-cn/docs/introduction/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "介绍" 3 | linkTitle: "介绍" 4 | weight: 100 5 | date: 2021-03-29 6 | description: > 7 | Rust的介绍,以及Rust的资料收集 8 | --- 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/zh-cn/docs/introduction/edition.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust版本" 3 | linkTitle: "Rust版本" 4 | date: 2021-03-29 5 | weight: 105 6 | description: > 7 | Rust版本 8 | --- 9 | 10 | Edition Guide 官方英文版本: 11 | 12 | https://doc.rust-lang.org/edition-guide/ 13 | 14 | 中文翻译版本(已经不可访问): 15 | 16 | ~~https://erasin.wang/books/edition-guide-cn/~~ 17 | 18 | 补充说明:信息量很大。 -------------------------------------------------------------------------------- /content/zh-cn/docs/introduction/information.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "资料收集" 3 | linkTitle: "资料收集" 4 | date: 2021-03-29 5 | weight: 190 6 | description: > 7 | 收集Rust的各种资料 8 | --- 9 | 10 | ## 官方网站 11 | 12 | - https://www.rust-lang.org 13 | - [rustlang@twitter](https://twitter.com/rustlang) 14 | 15 | ## 社区 16 | 17 | - [Rust官方社区](https://www.rust-lang.org/community) 18 | - [Rust官方社区的中文区](https://www.rust-lang.org/zh-CN/): 19 | - [Rust中文](https://rustlang-cn.org/):非常新的Rust社区,有很多内容,而且更新维护很给力。 20 | - [Lib.rs](https://lib.rs/): 含有67000个Rust库和应用程序的索引。快速、轻量级、有观点、非官方的crates.io替代品。 21 | 22 | ## 文档 23 | 24 | - [标准库API文档](https://doc.rust-lang.org/std/) 25 | - [Rust Reference](https://doc.rust-lang.org/reference/index.html): Rust reference 文档,有中文翻译版本 [Rust语言规范](https://rustlang-cn.org/office/rust/reference/) 正在翻译过程中 26 | - [Rust编译错误索引](https://doc.rust-lang.org/error-index.html):发生编译错误时,可以通过索引找到具体错误解释 27 | - [rustdoc文档](https://doc.rust-lang.org/rustdoc/): `restdoc`工具的使用文档 28 | - [Rustonomicon](https://doc.rust-lang.org/reference/): rust的参考文档。但是目前并不完整,可能有遗漏和错误 29 | - [Unstable Book](https://doc.rust-lang.org/unstable-book/): 用于尚不稳定特性的文档 30 | - [Rustonomicon](https://doc.rust-lang.org/nomicon/): unsafe rust的黑暗艺术,有中文翻译版本 [Rust高级编程](https://rustlang-cn.org/office/rust/advrust/) 31 | - [The Cargo Book](https://doc.rust-lang.org/cargo/index.html): cargo使用介绍,有中文翻译版本 [Cargo教程](https://rustlang-cn.org/office/rust/cargo/) 正在进行中 32 | - [Rust Edition Guide](https://doc.rust-lang.org/nightly/edition-guide/introduction.html): Rust 版本指南,传递 Rust 不同版本之间大的变更信息 33 | - [Command line apps in Rust](https://rust-lang-nursery.github.io/cli-wg/#command-line-apps-in-rust): 在Rust中编写命令行程序 34 | 35 | Rust中文网站有一个Rust官方书籍的汇总页面: 36 | 37 | https://rustlang-cn.org/office/rust/ 38 | 39 | ## 书籍 40 | 41 | rust中文社区有个资源收集项目,里面有不少好书: 42 | 43 | https://github.com/rustlang-cn/resourses/tree/master/books 44 | 45 | ### The Rust Programming Language 46 | 47 | 官方书籍"The Rust Programming Language", 有[第一版](https://doc.rust-lang.org/stable/book/first-edition/)和[第二版](https://doc.rust-lang.org/stable/book/index.html)。其中第一版已经过时,第二版几乎是重写。这本书网上有电子版可以[下载](http://www.allitebooks.com/the-rust-programming-language/)。 48 | 49 | "The Rust Programming Language"中文翻译版本, [第一版翻译](https://kaisery.gitbooks.io/rust-book-chinese/content/)和[第二版翻译](https://rustlang-cn.org/office/rust/book/)。 50 | 51 | 是目前非常好的的Rust入门书籍。 52 | 53 | ### Rust异步编程 54 | 55 | 翻译自自官方[async-book](https://rust-lang.github.io/async-book/) 56 | 57 | ### Rust by Example 58 | 59 | 这本书的内容非常不错,强烈推荐给入门读者。就是内容稍微老了点。 60 | 61 | - [英文版在线阅读](https://rustbyexample.com/index.html) 62 | - [英文版本仓库](https://github.com/rust-lang/rust-by-example) 63 | - [中文翻译版在线阅读](https://rustwiki.org/zh-CN//rust-by-example/) 64 | - [中文翻译版仓库](https://github.com/rust-lang-cn/rust-by-example-cn): 最后更新时间:2017-10-03 65 | 66 | ## 资源 67 | 68 | ### Awesome Rust 69 | 70 | https://github.com/rust-unofficial/awesome-rust 71 | 72 | 最齐全的Rust资料列表 73 | 74 | Rust中文社区的 Awesome Rust: 75 | 76 | https://rustlang-cn.org/resourse/awesome/ 77 | 78 | ### 值得新手关注的Rust项目 79 | 80 | 适用于新手学习rust的项目有: 81 | 82 | - [mini redis](https://github.com/tokio-rs/mini-redis) 83 | - [async-graphql](https://github.com/sunli829/async-graphql) 84 | 85 | ### 资源介绍文章 86 | 87 | - [一些有用的关于Rust的网站和repo](https://dengjianping.github.io/2019/06/12/%E4%B8%80%E4%BA%9B%E6%9C%89%E7%94%A8%E7%9A%84%E5%85%B3%E4%BA%8ERust%E7%9A%84%E7%BD%91%E7%AB%99%E5%92%8Crepo.html) 88 | 89 | -------------------------------------------------------------------------------- /content/zh-cn/docs/ownership/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的所有权机制" 3 | linkTitle: "所有权" 4 | weight: 4000 5 | date: 2021-04-02 6 | description: Rust的所有权机制 7 | --- 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust类型系统" 3 | linkTitle: "类型系统" 4 | weight: 3000 5 | date: 2021-04-02 6 | --- 7 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/concept/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust类型通用概念" 3 | linkTitle: "通用概念" 4 | weight: 100 5 | date: 2021-11-30 6 | description: > 7 | Rust类型通用概念 8 | --- 9 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/concept/rust-bczd.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "[Rust编程之道笔记]通用概念" 3 | linkTitle: "[Rust编程之道笔记]" 4 | weight: 110 5 | date: 2021-04-02 6 | description: > 7 | Rust编程之道一书 3.1 节通用概念 8 | --- 9 | 10 | > 内容出处: Rust编程之道一书,第3章类型系统,3.1 通用概念 11 | 12 | ## 3.1 通用概念 13 | 14 | 15 | 16 | 所谓类型,其实就是对表示信息的值进行细粒度的区分。不同的类型占用的内存不同。与直接操作比特位相比,直接操作类型可以更安全、更有效的利用内存。 17 | 18 | 类型系统是编程语言的基础和核心。 19 | 20 | **在类型系统中,一切皆类型。**基于类型定义的一系列组合、运算和转换,可以看做类型的行为。 21 | 22 | ### 3.1.1 类型系统的作用 23 | 24 | - 排查错误:在编译期或者运行期进行类型检查。静态语言能在编译期排查出错误。 25 | - 抽象:类型容许开发者在更高层面上进行思考。 26 | - 文档:明确的类型声明可以表明程序的行为 27 | - 优化效率:对于静态编译语言,在编译期可以通过类型检查来优化操作,节省运行时时间 28 | - 类型安全 29 | - 类型安全的语言可以便面类型间的无效计算 30 | - 类型安全的语言还可以保证内存安全:避免空指针、悬垂指针和缓存区溢出等导致的内存安全问题 31 | - 类型安全的语言可以避免语义上的逻辑错误 32 | 33 | ### 3.1.2 类型系统的分类 34 | 35 | - 静态类型:在编译期进行类型检查 36 | - 动态类型:在运行期进行类型检查 37 | 38 | 编程语言: 39 | 40 | - 强类型:不容许类型的自动隐式转换,在强制转换前不同类型无法进行计算 41 | - 弱类型:容许类型的自动隐式转换 42 | 43 | ### 3.1.3 类型系统与多态性 44 | 45 | **多态类型系统**的定义:容许一段代码在不同的上下文中具有不同类型的类型系统。对于静态类型的语言而言,多态性的好处是可以在不影响类型丰富的前提下,为不同的类型编写通用的代码。 46 | 47 | 按照多态发生的时机来划分: 48 | 49 | - 静多态(Static Polymorphism) :发生在编译期,静多态牺牲灵活性获取性能 50 | - 动多态(Dynamic Polymorphism):发生在运行时,动多态牺牲性能获取灵活性。 51 | 52 | 动多态在运行时需要查表,占用较多空间,所以一般情况下都使用静多态。 53 | 54 | **Rust 语言同时支持静多态和动多态**,其中静多态是一种零成本抽象。 55 | 56 | 现代编程语言包含三种多态形式: 57 | 58 | - 参数化多态(Parametric polymorphism) 59 | 60 | 一般是静多态,实际就是指泛型。泛型使得语言极具表达力,同时也保证了静态类型安全。 61 | 62 | - Ad-hoc 多态(ad-hoc polymorphism) 63 | 64 | 也叫特定多态。 65 | 66 | Ad-hoc 多态是指同一种行为定义,在不同的上下文中会有不同的行为实现。 67 | 68 | Rust 受 Haskell 启发,使用 trait 来支持 Ad-hoc 多态。 69 | 70 | - 子类型多态(subtype polymorphism) 71 | 72 | 一般是动多态,常用于面向对象的语言中,如Java。子类型多态代表一种包含关系:父类型的值包含了子类型的值,所以子类型的值可以看成父类型的值。 73 | 74 | **Rust 中没有类型Java的继承概念,因此不存在子类型多态。** 75 | 76 | 总结:Rust 的类型系统目前只支持参数化多态和Ad-hoc多态,即泛型和trait。 77 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/convert/Deref/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Deref解引用" 3 | linkTitle: "Deref" 4 | weight: 510 5 | date: 2021-11-30 6 | description: > 7 | Rust的Deref解引用 8 | --- 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/convert/Deref/rust-bczd.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "[Rust编程之道笔记]Deref解引用" 3 | linkTitle: "[Rust编程之道笔记]" 4 | weight: 512 5 | date: 2021-11-30 6 | description: > 7 | Rust编程之道一书 3.5.1 Deref解引用 8 | --- 9 | 10 | ## 3.5.1 解引用 11 | 12 | rust 的隐式类型转换基本上只有自动解引用。自动解引用的目的主要是方便开发者使用智能指针。 13 | 14 | ### 自动解引用 15 | 16 | 自动解引用虽然是编译期来做的,但是自动解引用的行为可以由开发者来定义。 17 | 18 | 引用使用 `&` 操作符,而解引用使用 `*` 操作符。可以通过实现 Deref trait 来自定义解引用操作。 19 | 20 | Deref 有一个特性是强制隐式转换,规则是这样:如果有一个类型T实现了 `Deref` ,则该类型T的引用(或者智能指针)在应用的时候会被自动转换为类型U。 21 | 22 | Deref内部实现: 23 | 24 | ```rust 25 | pub trait Deref { 26 | type Target: ?Sized; 27 | fn deref(&self) -> &Self::Target; 28 | } 29 | 30 | pub trait DerefMut : Deref { 31 | fn deref_mut(&mut self) -> &mut Self::Target; 32 | } 33 | ``` 34 | 35 | DerefMut 和 Deref 类似,不过返回的是可变引用。 36 | 37 | 实现 Deref 的目的是**简化编程**,避免开发者自己手工转换。 38 | 39 | ### 手动解引用 40 | 41 | 如果某类型和其解引用目标类型中包含了相同的方法,编译期就不指导该用哪一个了,此时就需要手动解引用。 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/convert/From/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "From" 3 | linkTitle: "From" 4 | weight: 540 5 | date: 2021-11-30 6 | description: > 7 | Rust的From 8 | --- 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/convert/From/rust-bczd.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "[Rust编程之道笔记]From Trait" 3 | linkTitle: "[Rust编程之道笔记]" 4 | weight: 542 5 | date: 2021-12-06 6 | description: > 7 | Rust编程之道一书 3.5.3 From Trait 8 | --- 9 | 10 | ## 3.5.3 From和Into 11 | 12 | From 和 Into 是定义在 std::convert 模块中的trait,定义了 from 和 into 两个方法,互为反操作。 13 | 14 | ```rust 15 | pub trait From { 16 | fn from(T) -> Self; 17 | } 18 | pub trait Into { 19 | fn into(self) -> T; 20 | } 21 | ``` 22 | 23 | Into的默认规则:如果类型 U 实现了 `From`,则 T 类型实例调用 into 方法时可以转换为类型 U。 24 | 25 | 这是 rust 标准库中有一个默认的实现: 26 | 27 | ```rust 28 | impl Into for T where U: From 29 | ``` 30 | 31 | 32 | 33 | ### tryFrom 和 tryInto trait 34 | 35 | 是 From 和 Into 的错误处理版本,因为转型转换是有可能发生错误的,所以需要进行错误处理时就可以用 TryFrom 和 TryInto。 36 | 37 | 38 | 39 | ### AsRef 和 AsMut trait 40 | 41 | 将值分别转换为不可变引用和可变引用。 42 | 43 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/convert/Into/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Into" 3 | linkTitle: "Into" 4 | weight: 550 5 | date: 2021-11-30 6 | description: > 7 | Rust的Into 8 | --- 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/convert/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的类型转换" 3 | linkTitle: "类型转换" 4 | weight: 500 5 | date: 2021-11-30 6 | description: > 7 | Rust的类型转换 8 | --- 9 | 10 | 类型转换分为隐式类型转换(Implicit Type Conversion)和显式类型转换(Explicit Type Conversion): 11 | 12 | - 隐式类型转换: 由编译期或者解释器来完成,开发者并未参与,所以又称之为强制类型转换(Type Coercion) 13 | - 显式类型转换: 由开发者指定,即一般意义上的类型转换(Type cast) 14 | 15 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/convert/as/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "as操作符" 3 | linkTitle: "as" 4 | weight: 520 5 | date: 2021-11-30 6 | description: > 7 | Rust的as操作符 8 | --- 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/convert/as/rust-bczd.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "[Rust编程之道笔记]as操作符" 3 | linkTitle: "[Rust编程之道笔记]" 4 | weight: 522 5 | date: 2021-12-06 6 | description: > 7 | Rust编程之道一书 3.5.2 as操作符 8 | --- 9 | 10 | ## 3.5.2 as操作符 11 | 12 | as 操作符最常用的场景就是转换 rust 中的基本数据类型。 13 | 14 | as 关键字不支持重载。 15 | 16 | 长类型转换为短类型的时候会被 截断处理。 17 | 18 | ### 无歧义完全限定语法 19 | 20 | 为结构体实现多个trait时,可能会出现同名的方法,使用 as 操作符可以帮助避免歧义。 21 | 22 | ```rust 23 | fn main() { 24 | let s = S(1); 25 | // 当 trait 的静态函数来调用 26 | A::test(&s, 1); 27 | B::test(&s, 1); 28 | // 使用as操作符 29 | ::test(&s, 1); 30 | ::test(&s, 1); 31 | } 32 | ``` 33 | 34 | ### 类型和子类型相互转换 35 | 36 | as转换可以用于类型和子类型之间的转换。 37 | 38 | `&'static str'` 类型是 `&'a str'` 类型的子类型。两者的生命周期标记不同,`'a` 和 `'static` 都是生命周期标记,其中 `'a` 是泛型标记,是 &str 的通用形式,而 `'static` 则是特指静态生命周期的 &str 字符串。 39 | 40 | ```rust 41 | fn main() { 42 | let a: &'static str = "hello"; // 'static str 43 | let b: &str = a as &str; // &str 44 | let c: &'static str = b as &'static str; // 'static str 45 | } 46 | ``` 47 | 48 | 可以通过 as 操作符将 `&'static str'` 和 `&'a str'` 相互转换。 49 | 50 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/generic/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的范型" 3 | linkTitle: "范型" 4 | weight: 300 5 | date: 2021-04-02 6 | description: > 7 | Rust的范型 8 | --- 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/generic/generic.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的范型概述" 3 | linkTitle: "范型概述" 4 | weight: 301 5 | date: 2021-04-02 6 | description: > 7 | Rust的范型概述 8 | --- 9 | 10 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/generic/rust-bczd.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "[Rust编程之道笔记]泛型" 3 | linkTitle: "[Rust编程之道笔记]" 4 | weight: 310 5 | date: 2021-11-29 6 | description: > 7 | Rust编程之道一书 3.3 节泛型 8 | --- 9 | 10 | > 内容出处: Rust编程之道一书,第3.3节泛型 11 | 12 | ## 3.3 泛型 13 | 14 | Rust的泛型是参数化多态。简单说就是把泛化的类型作为参数,单个类型可以抽象为一簇类型。 15 | 16 | ### 泛型的实现 17 | 18 | #### 泛型类型 19 | 20 | 类似 Box, Option, Result 都是泛型类型。 21 | 22 | #### 泛型函数 23 | 24 | ```rust 25 | fn foo(x: T) -> T { 26 | return x; 27 | } 28 | ``` 29 | 30 | #### 泛型结构体 31 | 32 | ```rust 33 | struct Point { 34 | x: T, 35 | y: T, 36 | } 37 | impl Point { 38 | fn new(x:T, y:T) -> Self { 39 | Point{x:x, y:y} 40 | } 41 | } 42 | ``` 43 | 44 | #### 泛型枚举 45 | 46 | TDB 47 | 48 | ### 泛型单态化 49 | 50 | Rust的泛型是静多态,是编译期多态,在编译期会被单态化(Monomorphization)。 51 | 52 | 单态化意味着编译期要将一个泛型函数生成多个具体类型对应的函数。 53 | 54 | 泛型和单态化是 Rust 最重要的功能。 55 | 56 | 单态化静态分发的好处是性能好,没有运行时开销;缺点是容易造成编译后生成的二进制文件膨胀。 57 | 58 | ### 3.3.2 泛型返回值自动推导 59 | 60 | 编译期可以对泛型进行自动推导。 61 | 62 | ```rust 63 | #[derive(Debug, PartialEq)] 64 | struct Foo(i32); 65 | #[derive(Debug, PartialEq)] 66 | struct Bar(i32, i32); 67 | trait Inst { 68 | fn new(i: i32) -> Self; 69 | } 70 | impl Inst for Foo { 71 | fn new(i: i32) -> Foo { 72 | Foo(i) 73 | } 74 | } 75 | impl Inst for Bar { 76 | fn new(i: i32) -> Bar { 77 | Bar(i, i + 10) 78 | } 79 | } 80 | // 泛型函数,返回值是泛型 81 | fn foobar(i: i32) -> T { 82 | T::new(i) 83 | } 84 | // 指定泛型类型为Foo,因此foobar实现中调用的是 Foo::new(i) 85 | let f: Foo = foobar(10); 86 | assert_eq!(f, Foo(10)); 87 | // 指定泛型类型为Bar,因此foobar实现中调用的是 Bar::new(i) 88 | let b: Bar = foobar(20); 89 | assert_eq!(b, Bar(20, 30)); 90 | ``` 91 | 92 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/overview/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust类型系统概述" 3 | linkTitle: "系统概述" 4 | weight: 200 5 | date: 2021-04-02 6 | description: > 7 | Rust类型系统概述 8 | --- 9 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/overview/derivation/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust类型推导" 3 | linkTitle: "类型推导" 4 | weight: 220 5 | date: 2021-11-30 6 | description: > 7 | Rust类型推导 8 | --- 9 | 10 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/overview/derivation/rust-bczd.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "[Rust编程之道笔记]类型推导" 3 | linkTitle: "[Rust编程之道笔记]" 4 | weight: 221 5 | date: 2021-04-02 6 | description: > 7 | Rust编程之道一书 3.2.2 节类型推导 8 | --- 9 | 10 | > 内容出处: Rust编程之道一书,第3章类型系统,3.2.2 类型推导 11 | 12 | ## 3.2.2 类型推导 13 | 14 | Rust 只能在局部范围内进行类型推导。 15 | 16 | 17 | 18 | ### Turbofish操作符 19 | 20 | 当 Rust 无法从上下文中自动推导出类型的时候,编译期会通过错误信息提示并要求添加类型标注。 21 | 22 | 标注类型的方式: 23 | 24 | ```rust 25 | fn main() { 26 | let x = "1"; 27 | //标注变量的类型 28 | let int_x : i32 = x.parse().unwrap(); 29 | //通过 Turbofish操作符 标注 30 | assert_eq!(x.parse::().unwrap(), 1); 31 | } 32 | ``` 33 | 34 | ### 类型推导的不足 35 | 36 | 总结:rust的类型推导还不够强大, 因此,编码时推荐尽量显式声明类型,避免麻烦。 37 | 38 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/overview/size/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust类型大小" 3 | linkTitle: "类型大小" 4 | weight: 210 5 | date: 2021-11-30 6 | description: > 7 | Rust类型大小 8 | --- 9 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/overview/size/rust-bczd.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "[Rust编程之道笔记]类型大小" 3 | linkTitle: "[Rust编程之道笔记]" 4 | weight: 211 5 | date: 2021-04-02 6 | description: > 7 | Rust编程之道一书 3.2.1 节类型大小 8 | --- 9 | 10 | > 内容出处: Rust编程之道一书,第3章类型系统,3.2.1 类型大小 11 | 12 | ## 3.2 类型大小 13 | 14 | 编程语言中不同的类型本质上是内存占用空间和编码方式的不同,Rust也不例外。Rust没有GC,内存首先由编译期来分配,rust代码首先由编译期来分配, Rust 代码被编译为 LLVM IR,其中携带了内存分配的信息。 15 | 16 | 因此,**Rust编译器需要实现知道类型的大小,才能分配合理的内存**。 17 | 18 | #### 可确定大小类型和动态大小类型 19 | 20 | Rust 中绝大部分类型都是在编译期内可确定大小的类型(称为Sized Type),也有少量的动态大小的类型(Dynamic Sized Type,简写为 DST)。 21 | 22 | 对于DST,Rust提供了引用类型,因为引用总会有固定且在编译期已知的大小。如字符串切片 `&str` 就是一种引用类型 ,由指针和长度信息组成。 23 | 24 | #### 零大小类型 25 | 26 | 除了可确定大小类型和 DST 类型,Rust 还支持零大小类型(Zero Sized Type, ZST),如单元类型和单元结构体。 27 | 28 | - 单元类型和单元结构体大小为零 29 | - 由单元类型组成的数组大小也为零 30 | 31 | ZST类型的特点是:值就是本身,运行时并不占用内存空间。 32 | 33 | ### 底类型 34 | 35 | 底类型(Bottom type)是院子类型理论的术语,其实是 never 类型,它的特点是: 36 | 37 | - 没有值 38 | - 是其他任意类型的子类型 39 | 40 | 如果说 ZST 类型表示“空”的话,那么底类型就是表示“无”。 41 | 42 | Rust 中的底类型用 `!` 表示,也被称为 Bang Type。 43 | 44 | Rust 中有很多中情况确实没有值,但是为了类型安全,必须归入类型系统进行统一处理,这些情况包括: 45 | 46 | - 发散函数(Diverging Function):指会导致线程崩溃的 `panic!` 或者用于退出函数的 `std::process::exit`。 47 | - `continue` 和 `break` 关键字: 只是表示流程的跳转,并不会返回什么 48 | - `loop` 循环:虽然可以返回某个值,但是也有需要无限循环的时候 49 | - 空枚举,比如 `enum Void{}` 50 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/trait/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的Trait" 3 | linkTitle: "Trait" 4 | weight: 400 5 | date: 2021-04-02 6 | description: Rust的Trait 7 | --- 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/trait/trait-object/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust中的Trait Object" 3 | linkTitle: "Trait Object" 4 | weight: 450 5 | date: 2021-11-30 6 | description: Rust中的Trait Object 7 | --- 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/trait/trait-object/trait-object.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust中的Trait Object" 3 | linkTitle: "Trait Object" 4 | weight: 451 5 | date: 2021-11-30 6 | description: Rust中的Trait Object 7 | --- 8 | 9 | 10 | 11 | ### 参考资料 12 | 13 | - [Rust, Builder Pattern, Trait Objects, Box and Rc](https://abronan.com/rust-trait-objects-box-and-rc/): 这个文章不错,讲清楚了 `Box` 和 `Rc` 的差别,还有对 Trait Object 的使用 14 | - [All About Trait Objects](https://brson.github.io/rust-anthology/1/all-about-trait-objects.html#all-about-trait-objects) 15 | - [trait object](https://zhuanlan.zhihu.com/p/23791817) 16 | 17 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/trait/trait.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust的Trait概述" 3 | linkTitle: "概述" 4 | weight: 401 5 | date: 2021-04-02 6 | description: Rust的Trait概述 7 | --- 8 | 9 | -------------------------------------------------------------------------------- /content/zh-cn/docs/type/type.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust类型系统概述" 3 | linkTitle: "概述" 4 | weight: 1 5 | date: 2021-04-02 6 | description: > 7 | Rust类型系统概述 8 | --- 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/zh-cn/featured-background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/content/zh-cn/featured-background.jpg -------------------------------------------------------------------------------- /content/zh-cn/search.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 搜索结果 3 | layout: search 4 | --- 5 | 6 | -------------------------------------------------------------------------------- /content/zh-cn/std/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库学习" 4 | linkTitle: "标准库" 5 | weight: 1 6 | date: 2021-11-29 7 | menu: 8 | main: 9 | weight: 30 10 | pre: 11 | cascade: 12 | type: "docs" 13 | --- 14 | 15 | {{% pageinfo %}} 16 | Rust标准库学习 17 | {{% /pageinfo %}} 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /content/zh-cn/std/async/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的异步" 4 | linkTitle: "异步" 5 | weight: 500 6 | date: 2021-04-02 7 | description: Rust标准库中的异步 8 | --- 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/zh-cn/std/async/async.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的异步编程" 4 | linkTitle: "异步编程" 5 | weight: 401 6 | date: 2021-04-02 7 | description: Rust标准库中的异步编程 8 | --- 9 | 10 | 11 | 12 | ### 资料 13 | 14 | - [Asynchronous Programming in Rust](https://rust-lang.github.io/async-book/): Rust官方的 async book 15 | - [中文翻译版本](https://huangjj27.github.io/async-book/index.html) 16 | - [Rust 异步编程](https://learnku.com/docs/async-book/2018): 另一个翻译版本 17 | - [async-std 中文文档](https://learnku.com/docs/rust-async-std/) 18 | 19 | -------------------------------------------------------------------------------- /content/zh-cn/std/borrow/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的借用(borrow)" 4 | linkTitle: "借用(borrow)" 5 | weight: 900 6 | date: 2021-04-02 7 | description: Rust标准库中的借用(borrow) 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /content/zh-cn/std/borrow/borrow.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的借用介绍" 4 | linkTitle: "借用介绍" 5 | weight: 901 6 | date: 2021-04-02 7 | description: Rust标准库中的借用介绍 8 | --- 9 | 10 | https://doc.rust-lang.org/std/borrow/index.html 11 | 12 | 用于处理借用(borrow)数据的模块。 13 | 14 | ## Cow 枚举 15 | 16 | ```rust 17 | pub enum Cow<'a, B> where 18 | B: 'a + ToOwned + ?Sized, { 19 | Borrowed(&'a B), 20 | Owned(::Owned), 21 | } 22 | ``` 23 | 24 | clone-on-write 智能指针。 25 | 26 | cow = Clone On Write 27 | 28 | 类型Cow是一个智能指针,提供了 clone-on-write 功能:它可以封装并提供对借用数据的不可变访问,当需要可变或所有权时,可以延迟克隆数据。该类型是通过 Borrow trait 来处理一般的借用数据。 29 | 30 | Cow 实现了 Deref,这意味着你可以直接在它所封装的数据上调用非可变方法。如果需要改变,to_mut 将获得一个到拥有值的可变引用,必要时进行克隆。 31 | 32 | ```rust 33 | use std::borrow::Cow; 34 | 35 | fn abs_all(input: &mut Cow<[i32]>) { 36 | for i in 0..input.len() { 37 | let v = input[i]; 38 | if v < 0 { 39 | // Clones into a vector if not already owned. 40 | input.to_mut()[i] = -v; 41 | } 42 | } 43 | } 44 | 45 | // No clone occurs because `input` doesn't need to be mutated. 46 | let slice = [0, 1, 2]; 47 | let mut input = Cow::from(&slice[..]); 48 | abs_all(&mut input); 49 | 50 | // Clone occurs because `input` needs to be mutated. 51 | let slice = [-1, 0, 1]; 52 | let mut input = Cow::from(&slice[..]); 53 | abs_all(&mut input); 54 | 55 | // No clone occurs because `input` is already owned. 56 | let mut input = Cow::from(vec![-1, 0, 1]); 57 | abs_all(&mut input); 58 | ``` 59 | 60 | ### Borrow Trait 61 | 62 | 借用数据的特征。 63 | 64 | 在Rust中,常见的是为不同的用例提供不同的类型表示。例如,可以通过诸如Box或Rc这样的指针类型来具体选择值的存储位置和管理,以适合特定的使用情况。除了这些可以与任何类型一起使用的通用封装器之外,有些类型还提供了可选的面,提供了潜在的有开销的功能。这类类型的一个例子是String,它为基本的str增加了扩展字符串的能力。这需要为一个简单的、不可更改的字符串保留不必要的附加信息。 65 | 66 | 这些类型通过对该数据的类型的引用来提供对底层数据的访问。它们被说成是 "borrow/借用 "该类型。例如,Box可以被借用为T,而String可以被借用为str。 67 | 68 | 类型表示它们可以通过实现Borrow,在trait的borrow方法中提供对T的引用来表示它们可以被借用为某种类型T。一个类型可以自由地借用为多个不同类型。如果它希望可变地借用为类型--允许修改底层数据,可以额外实现BorrowMut。 69 | 70 | 此外,在为附加的特征提供实现时,需要考虑到它们是否应该与底层类型的行为完全相同,因为它们作为底层类型的表示方式。当依赖这些额外的特征实现的行为相同时,通用代码通常会使用Borrow。这些特征很可能会作为附加的特征边界出现。 71 | 72 | 特别是Eq、Ord和Hash对于借用值和拥有值必须是等价的:`x.borrow()==y.borrow()` 应该给出与 `x==y` 相同的结果。 73 | 74 | 如果通用代码仅仅需要对所有能够提供相关类型T的引用的类型进行工作,那么通常最好使用AsRef,因为更多的类型可以安全地实现它。 75 | 76 | 例子: 77 | 78 | 作为一个数据集合,HashMap同时拥有键和值。如果键的实际数据被封装在某种管理类型中,但是,应该还是可以使用对键的数据引用来搜索值。例如,如果键是一个字符串,那么它很可能是用哈希图作为String存储的,而应该可以用&str来搜索。因此,insert需要对String进行操作,而get需要能够使用&str。 79 | 80 | 稍微简化一下,HashMap的相关部分看起来像这样。 81 | 82 | ```rust 83 | use std::borrow::Borrow; 84 | use std::hash::Hash; 85 | 86 | pub struct HashMap { 87 | // fields omitted 88 | } 89 | 90 | impl HashMap { 91 | pub fn insert(&self, key: K, value: V) -> Option 92 | where K: Hash + Eq 93 | { 94 | // ... 95 | } 96 | 97 | pub fn get(&self, k: &Q) -> Option<&V> 98 | where 99 | K: Borrow, 100 | Q: Hash + Eq + ?Sized 101 | { 102 | // ... 103 | } 104 | } 105 | ``` 106 | 107 | 整个hash map是通用于一个key类型K,由于这些key是和hash map一起存储的,所以这个类型必须拥有该密钥的数据。当插入一个键-值对时,map被赋予了这样一个K,需要找到正确的hash map,并根据这个K来检查这个键是否已经存在。 108 | 109 | 然而,当在地图中搜索一个值时,必须提供一个K的引用作为要搜索的键,这就需要始终创建这样一个拥有的值。对于字符串键,这就意味着需要创建一个String值来搜索只有str的情况。 110 | 111 | 相反,get方法是通用于底层键数据的类型,在上面的方法签名中称为Q。它通过要求K:Borrow来说明K借入为Q。通过额外要求Q:Hash + Eq,它表明要求K和Q都有Hash和Eq特征的实现,产生相同的结果。 112 | 113 | get的实现特别依赖于Hash的相同实现,通过在Q值上调用Hash::hash来确定密钥的哈希桶,即使它是根据从K值计算出的哈希值插入了key。 114 | 115 | 因此,如果一个包裹Q值的K产生的散列值与Q不同,那么hash map就会被破坏。 116 | 117 | ```rust 118 | pub struct CaseInsensitiveString(String); 119 | 120 | impl PartialEq for CaseInsensitiveString { 121 | fn eq(&self, : &Self) -> bool { 122 | self.0.eq_ignore_ascii_case(&other.0) 123 | } 124 | } 125 | 126 | impl Eq for CaseInsensitiveString { } 127 | ``` 128 | 129 | 因为两个相等的值需要产生相同的散列值,所以Hash的实现也需要忽略ASCII 大小写: 130 | 131 | ```rust 132 | impl Hash for CaseInsensitiveString { 133 | fn hash(&self, state: &mut H) { 134 | for c in self.0.as_bytes() { 135 | c.to_ascii_lowercase().hash(state) 136 | } 137 | } 138 | } 139 | ``` 140 | 141 | CaseInsensitiveString可以实现Borrow吗?当然可以,它当然可以通过它所包含的自有字符串来提供对字符串片的引用。但由于它的Hash实现不同,它的行为方式与str不同,因此事实上不能实现Borrow。如果它想允许别人访问底层的str,可以通过AsRef来实现,而AsRef没有任何额外的要求。 142 | 143 | ### BorrowMut Trait 144 | 145 | 用于可变地借用数据的特征。 146 | 147 | 作为 Borrow 的附属属性,该特征允许一个类型通过提供一个可变的引用来借用作为底层类型。关于作为另一个类型借入的更多信息,请参阅 Borrow。 148 | 149 | ### ToOwned Trait 150 | 151 | 用于借用数据的Clone泛化。 152 | 153 | 一些类型使其可以从借用数据到拥有数据,通常是通过实现Clone特征。但Clone只适用于从&T到T。ToOwned特征将Clone泛化为从给定类型的任何借入数据中构造出拥有的数据。 -------------------------------------------------------------------------------- /content/zh-cn/std/boxed/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的Boxed" 4 | linkTitle: "Boxed" 5 | weight: 800 6 | date: 2021-04-02 7 | description: Rust标准库中的Boxed 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /content/zh-cn/std/boxed/boxed.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的Boxed介绍" 4 | linkTitle: "Boxed介绍" 5 | weight: 801 6 | date: 2021-04-02 7 | description: Rust标准库中的Boxed介绍 8 | --- 9 | 10 | https://doc.rust-lang.org/std/boxed/index.html 11 | 12 | 用于堆分配的指针类型。 13 | 14 | Box,被随意称为 "box",在Rust中提供了最简单的堆分配形式。Box为这个分配提供了所有权,当它们超出范围时,会丢弃它们的内容。 15 | 16 | ### 例子 17 | 18 | 通过创建Box,将值从栈中移动到堆中: 19 | 20 | ```rust 21 | let val: u8 = 5; 22 | let boxed: Box = Box::new(val); 23 | ``` 24 | 25 | 通过取消引用([dereferencing](https://doc.rust-lang.org/std/ops/trait.Deref.html))将值从Box中移回栈中: 26 | 27 | ```rust 28 | let boxed: Box = Box::new(5); 29 | let val: u8 = *boxed; 30 | ``` 31 | 32 | 创建一个递归数据结构: 33 | 34 | ```rust 35 | #[derive(Debug)] 36 | enum List { 37 | Cons(T, Box>), 38 | Nil, 39 | } 40 | 41 | let list: List = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil)))); 42 | println!("{:?}", list); 43 | ``` 44 | 45 | 这将打印出 `Cons(1, Cons(2, Nil))`。 46 | 47 | 递归结构必须是box,因为如果Cons的定义是这样的: 48 | 49 | ```rust 50 | Cons(T, List), 51 | ``` 52 | 53 | 这样做就不行了。这是因为List的大小取决于列表中有多少元素,所以我们不知道要为Cons分配多少内存。通过引入一个Box,它有一个定义的大小,我们就知道Cons需要多大。 54 | 55 | ### 内存布局 56 | 57 | TODO 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /content/zh-cn/std/cell/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的cell" 4 | linkTitle: "cell" 5 | weight: 1000 6 | date: 2021-04-02 7 | description: Rust标准库中的cell 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /content/zh-cn/std/cell/cell.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的cell介绍" 4 | linkTitle: "cell介绍" 5 | weight: 1001 6 | date: 2021-04-02 7 | description: Rust标准库中的cell介绍 8 | --- 9 | 10 | https://doc.rust-lang.org/std/cell/index.html 11 | 12 | 可共享的可变容器。 13 | 14 | Rust的内存安全就是基于这个规则。给定一个对象T,只可能有以下情况之一。 15 | 16 | - 有该对象的多个不可变的引用(&T)(也称为别名/**aliasing**)。 17 | - 有该对象的一个可变的引用(&mut T)(也称为可突变性/**mutability**)。 18 | 19 | 这是由Rust编译器强制执行的。但是,在有些情况下,这个规则不够灵活。有时需要对一个对象有多个引用,但又要对其进行改变。 20 | 21 | 可共享的可变容器的存在是为了允许以可控的方式进行修改,甚至在存在别名的情况下也是如此。Cell和RefCell都允许以单线程的方式进行改变。但是,Cell和RefCell都不是线程安全的(它们没有实现同步)。如果你需要在多个线程之间进行别名和改变,可以使用Mutex、RwLock或原子类型。 22 | 23 | Cell和RefCell类型的值可以通过共享引用(即通用的&T类型)进行改变,而大多数Rust类型只能通过唯一的(&mut T)引用进行突变。我们说Cell和RefCell提供了 "内部可变性",这与典型的Rust类型表现出 "继承可变性 "的典型Rust类型形成鲜明对比。 24 | 25 | Cell类型有两种风格:Cell和RefCell。Cell通过在Cell中移动值来实现内部内部。要使用引用代替值,必须使用RefCell类型,在改变之前获得一个写锁。Cell提供了获取和改变当前内部值的方法。 26 | 27 | - 对于实现Copy的类型,get方法可以检索当前的内部值。 28 | - 对于实现Default的类型,take方法用Default::default()替换当前内部值,并返回被替换的值。 29 | - 对于所有类型,replace方法替换了当前的内部值并返回被替换的值,而 into_inner方法则消费 Cell 并返回内部值。此外,set方法替换了内部值,丢弃了被替换的值。 30 | 31 | RefCell使用Rust的生命期来实现 "动态借用/dynamic borrowing",这是一个可以对内部值进行临时的、排他性的、可变的访问的过程。RefCell的借用是 "在运行时 "跟踪的,不像Rust的原生引用类型完全是在编译时静态跟踪的。因为RefCell的借用是动态的,所以有可能试图借用一个已经被可变借用的值;当这种情况发生时,会导致线程恐慌。 32 | 33 | ### 何时选择内部可变性 34 | 35 | 比较常见的继承式可突变性,即必须有唯一的访问权限才能改变一个值,这是Rust语言的关键元素之一,它使Rust能够对指针别名进行有力的推理,从静态上防止了崩溃bug。正因为如此,继承式的可变性是首选,而内部可变性是不得已而为之。由于cell类型可以在不允许改变的地方进行改变,因此在某些情况下,内部突变可能是合适的,甚至是必须使用的,例如: 36 | 37 | - 在不可变的事物 "内部"引入可变性 38 | - 逻辑上不可变方法的实现细节。 39 | - Clone的可变实现。 40 | 41 | ### 在不变的事物内部引入可变性 42 | 43 | 许多共享的智能指针类型,包括Rc和Arc,都提供了可以在多方之间克隆和共享的容器。由于所包含的值可能是多义性的,所以只能用&,而不是&mut来借用。如果没有cell,就根本不可能对这些智能指针里面的数据进行改变。 44 | 45 | 那么,在共享指针类型里面放一个RefCell来重新引入可变性是很常见的。 46 | 47 | ```rust 48 | use std::cell::{RefCell, RefMut}; 49 | use std::collections::HashMap; 50 | use std::rc::Rc; 51 | 52 | fn main() { 53 | let shared_map: Rc> = Rc::new(RefCell::new(HashMap::new())); 54 | // Create a new block to limit the scope of the dynamic borrow 55 | { 56 | let mut map: RefMut<_> = shared_map.borrow_mut(); 57 | map.insert("africa", 92388); 58 | map.insert("kyoto", 11837); 59 | map.insert("piccadilly", 11826); 60 | map.insert("marbles", 38); 61 | } 62 | 63 | // Note that if we had not let the previous borrow of the cache fall out 64 | // of scope then the subsequent borrow would cause a dynamic thread panic. 65 | // This is the major hazard of using `RefCell`. 66 | let total: i32 = shared_map.borrow().values().sum(); 67 | println!("{}", total); 68 | } 69 | ``` 70 | 71 | 注意,这个例子使用的是Rc而不是Arc。RefCell用于单线程场景。如果你需要在多线程场景中使用RwLock或Mutex,可以考虑使用RwLock或Mutex。 72 | 73 | ### 逻辑上不可更改的方法的实施细节 74 | 75 | 偶尔,在API中不公开 "在引擎盖下 "发生的修改可能是可取的。这可能是因为在逻辑上,操作是不可更改的,但例如,缓存会迫使实现者执行突变;也可能是因为你必须使用可变来实现一个trait方法,而这个trait方法最初定义为取&self。 76 | 77 | ```rust 78 | use std::cell::RefCell; 79 | 80 | struct Graph { 81 | edges: Vec<(i32, i32)>, 82 | span_tree_cache: RefCell>> 83 | } 84 | 85 | impl Graph { 86 | fn minimum_spanning_tree(&self) -> Vec<(i32, i32)> { 87 | self.span_tree_cache.borrow_mut() 88 | .get_or_insert_with(|| self.calc_span_tree()) 89 | .clone() 90 | } 91 | 92 | fn calc_span_tree(&self) -> Vec<(i32, i32)> { 93 | // Expensive computation goes here 94 | vec![] 95 | } 96 | } 97 | ``` 98 | 99 | ### Clone的可变实现 100 | 101 | 这只是前者的一个特殊但是很常见的案例:隐藏看起来是不可改的操作中的可变性。克隆方法预计不会改变源值,并且声明取&self,而不是&mut self。因此,克隆方法中发生的任何改变都必须使用cell类型。例如,Rc在Cell中维护其引用计数。 -------------------------------------------------------------------------------- /content/zh-cn/std/clone/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的克隆(clone)" 4 | linkTitle: "克隆(clone)" 5 | weight: 1100 6 | date: 2021-04-02 7 | description: Rust标准库中的克隆(clone) 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /content/zh-cn/std/clone/clone.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的克隆介绍" 4 | linkTitle: "克隆介绍" 5 | weight: 1101 6 | date: 2021-04-02 7 | description: Rust标准库中的克隆介绍 8 | --- 9 | 10 | https://doc.rust-lang.org/std/clone/index.html 11 | 12 | 克隆特性,用于不能 "隐式复制 "的类型。 13 | 14 | 在Rust中,一些简单的类型是 "隐式复制 "的,当你分配它们或传递它们作为参数时,接收方会得到一个副本,保留原值。这些类型不需要分配器来复制,也没有finalizers器(也就是说,它们不包含拥有的box或实现Drop),所以编译器认为它们的复制很便宜,也很安全。对于其他类型,必须显式地进行复制,通过实现Clone特征并调用clone方法。 15 | 16 | 基本用法示例: 17 | 18 | ``` 19 | let s = String::new(); // String type implements Clone 20 | let copy = s.clone(); // so we can clone it 21 | ``` 22 | 23 | 为了方便地实现Clone特征,也可以使用 ``#[derive(Clone)]``。例子: 24 | 25 | ```rust 26 | #[derive(Clone)] // we add the Clone trait to Morpheus struct 27 | struct Morpheus { 28 | blue_pill: f32, 29 | red_pill: i64, 30 | } 31 | 32 | fn main() { 33 | let f = Morpheus { blue_pill: 0.0, red_pill: 0 }; 34 | let copy = f.clone(); // and now we can clone it! 35 | } 36 | ``` -------------------------------------------------------------------------------- /content/zh-cn/std/collections/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的集合" 4 | linkTitle: "集合" 5 | weight: 200 6 | date: 2021-04-02 7 | description: Rust标准库中的集合 8 | --- 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust标准库中的标记(Marker)模块" 3 | linkTitle: "标记(Marker)" 4 | weight: 1300 5 | date: 2021-12-01 6 | description: > 7 | Rust标准库中的标记(Marker)模块 8 | --- 9 | 10 | 原生 traits 和类型表示类型的基本属性。 11 | 12 | Rust 类型可以根据其固有属性以各种有用的方式进行分类。 这些分类表示为 traits。 13 | 14 | https://doc.rust-lang.org/std/marker/index.html 15 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/copy/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Copy trait" 3 | linkTitle: "Copy trait" 4 | weight: 1330 5 | date: 2021-12-01 6 | description: > 7 | 只需复制位即可复制其值的类型。 8 | --- 9 | 10 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/copy/rust-bczd.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "[Rust编程之道笔记]Copy trait" 3 | linkTitle: "[Rust编程之道笔记]" 4 | weight: 1334 5 | date: 2021-12-01 6 | description: > 7 | Rust编程之道一书 3.4.4 标签trait 8 | --- 9 | 10 | 11 | 12 | copy trait 用来标识可以按位复制其值的类型,按位复制等价于c语言中的 memcpy。 13 | 14 | ```rust 15 | pub trait Copy: Clone { } 16 | ``` 17 | 18 | copy trait 继承自 clone trait,意味着要实现 Copy trait 的类型,必须实现 Clone trait 中定义的方法。 19 | 20 | 要实现 Copy trait,就必须同时实现 Clone trait。 21 | 22 | ```rust 23 | struct MyStruct; 24 | 25 | impl Copy for MyStruct { } 26 | 27 | impl Clone for MyStruct { 28 | fn clone(&self) -> MyStruct { 29 | *self 30 | } 31 | } 32 | ``` 33 | 34 | rust提供了更方便的 derive 属性: 35 | 36 | ```rust 37 | #[derive(Copy, Clone)] 38 | struct MyStruct; 39 | ``` 40 | 41 | copy 的行为是隐式行为,开发者不能重载 Copy 行为,它永远都是一个简单的位复制。 42 | 43 | 并非所有的类型都可以实现 Copy trait。 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/copy/source.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Copy trait的源码" 3 | linkTitle: "源码" 4 | weight: 1333 5 | date: 2021-12-01 6 | description: > 7 | Copy trait的源码 8 | --- 9 | 10 | https://github.com/rust-lang/rust/blob/master/library/core/src/marker.rs 11 | 12 | ```rust 13 | #[stable(feature = "rust1", since = "1.0.0")] 14 | #[lang = "copy"] 15 | #[rustc_unsafe_specialization_marker] 16 | pub trait Copy: Clone { 17 | // Empty. 18 | } 19 | ``` 20 | 21 | 原始类型的Copy的实现。 22 | 23 | 无法在Rust中描述的实现是在 rustc_trait_selection 中的 `traits::SelectionContext::copy_clone_conditions()` 中实现。 24 | 25 | ```rust 26 | mod copy_impls { 27 | 28 | use super::Copy; 29 | 30 | macro_rules! impl_copy { 31 | ($($t:ty)*) => { 32 | $( 33 | #[stable(feature = "rust1", since = "1.0.0")] 34 | impl Copy for $t {} 35 | )* 36 | } 37 | } 38 | 39 | impl_copy! { 40 | usize u8 u16 u32 u64 u128 41 | isize i8 i16 i32 i64 i128 42 | f32 f64 43 | bool char 44 | } 45 | 46 | #[unstable(feature = "never_type", issue = "35121")] 47 | impl Copy for ! {} 48 | 49 | #[stable(feature = "rust1", since = "1.0.0")] 50 | impl Copy for *const T {} 51 | 52 | #[stable(feature = "rust1", since = "1.0.0")] 53 | impl Copy for *mut T {} 54 | 55 | /// Shared references can be copied, but mutable references *cannot*! 56 | #[stable(feature = "rust1", since = "1.0.0")] 57 | impl Copy for &T {} 58 | } 59 | ``` 60 | 61 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/copy/std-doc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Copy trait的std文档" 3 | linkTitle: "std文档" 4 | weight: 1332 5 | date: 2021-12-01 6 | description: > 7 | Copy trait的std文档 8 | --- 9 | 10 | https://doc.rust-lang.org/std/marker/trait.Copy.html 11 | 12 | ```rust 13 | pub trait Copy: Clone { } 14 | ``` 15 | 16 | 只需复制位即可复制其值的类型。 17 | 18 | 默认情况下,变量绑定具有 `move语义`。换句话说: 19 | 20 | ```rust 21 | #[derive(Debug)] 22 | struct Foo; 23 | 24 | let x = Foo; 25 | 26 | let y = x; 27 | 28 | // `x` 已移至 `y`,因此无法使用 29 | 30 | // println!("{:?}", x); // error: use of moved value 31 | ``` 32 | 33 | 但是,如果类型实现 `Copy`,则它具有复制语义: 34 | 35 | ```rust 36 | // 我们可以派生一个 `Copy` 实现。 37 | // `Clone` 也是必需的,因为它是 `Copy` 的父特征。 38 | #[derive(Debug, Copy, Clone)] 39 | struct Foo; 40 | 41 | let x = Foo; 42 | 43 | let y = x; 44 | 45 | // `y` 是 `x` 的副本 46 | 47 | println!("{:?}", x); // A-OK! 48 | ``` 49 | 50 | 重要的是要注意,在这两个示例中,唯一的区别是分配后是否允许您访问 `x`。 在后台,复制(copy)和移动(move)都可能导致将位复制到内存中,尽管有时会对其进行优化。 51 | 52 | ### 如何实现 `Copy`? 53 | 54 | 有两种方法可以在您的类型上实现 `Copy`。最简单的是使用 `derive`: 55 | 56 | ```rust 57 | #[derive(Copy, Clone)] 58 | struct MyStruct; 59 | ``` 60 | 61 | 您还可以手动实现 `Copy` 和 `Clone`: 62 | 63 | ```rust 64 | struct MyStruct; 65 | 66 | impl Copy for MyStruct { } 67 | 68 | impl Clone for MyStruct { 69 | fn clone(&self) -> MyStruct { 70 | *self 71 | } 72 | } 73 | ``` 74 | 75 | 两者之间的区别很小: `derive` 策略还将 `Copy` 绑定在类型参数上,这并不总是需要的。 76 | 77 | ### `Copy` 和 `Clone` 有什么区别? 78 | 79 | 复制是隐式发生的,例如作为分配 `y = x` 的一部分。`Copy` 的行为不可重载; 它始终是简单的按位复制。 80 | 81 | 克隆是一个明确的动作 `x.clone()`。`Clone` 的实现可以提供安全复制值所需的任何特定于类型的行为。 例如,用于 `String`的 `Clone` 的实现需要在堆中复制指向字符串的缓冲区。 `String` 值的简单按位副本将仅复制指针,从而导致该行向下双重释放。 因此,`String`是 `Clone`,但不是 `Copy`。 82 | 83 | `Clone` 是 `Copy` 的父特征,因此 `Copy` 的所有类型也必须实现 `Clone`。 如果类型为 `Copy`,则其 `Clone` 实现仅需要返回 `*self` (请参见上面的示例)。 84 | 85 | ### 类型何时可以是 `Copy`? 86 | 87 | 如果类型的所有组件都实现 `Copy`,则它可以实现 `Copy`。例如,此结构体可以是 `Copy`: 88 | 89 | ```rust 90 | #[derive(Copy, Clone)] 91 | struct Point { 92 | x: i32, 93 | y: i32, 94 | } 95 | ``` 96 | 97 | 一个结构体可以是 `Copy`,而 `i32` 是 `Copy`,因此 `Point` 有资格成为 `Copy`。 相比之下,考虑 98 | 99 | ```rust 100 | struct PointList { 101 | points: Vec, 102 | } 103 | ``` 104 | 105 | 结构体 `PointList` 无法实现 `Copy`,因为 `Vec` 不是 `Copy`。如果尝试派生 `Copy` 实现,则会收到错误消息: 106 | 107 | ```bash 108 | the trait `Copy` may not be implemented for this type; field `points` does not implement `Copy` 109 | ``` 110 | 111 | 共享引用 (`&T`) 也是 `Copy`,因此,即使类型中包含不是 *`Copy` 类型的共享引用 `T`,也可以是 `Copy`。 考虑下面的结构体,它可以实现 `Copy`,因为它从上方仅对我们的非 Copy 类型 `PointList` 持有一个 *shared 引用*: 112 | 113 | ```rust 114 | #[derive(Copy, Clone)] 115 | struct PointListWrapper<'a> { 116 | point_list_ref: &'a PointList, 117 | } 118 | ``` 119 | 120 | ### 什么时候类型不能为 `Copy`? 121 | 122 | 某些类型无法安全复制。例如,复制 `&mut T` 将创建一个别名可变引用。 复制 `String` 将重复管理 `String` 缓冲区,从而导致双重释放。 123 | 124 | 概括后一种情况,任何实现 `Drop` 的类型都不能是 `Copy`,因为它除了管理自己的 `size_of::` 字节外还管理一些资源。 125 | 126 | 果您尝试在包含非 `Copy` 数据的结构或枚举上实现 `Copy`,则会收到 [E0204](../../error-index.html#E0204) 错误。 127 | 128 | ### 什么时候类型应该是 `Copy`? 129 | 130 | 一般来说,如果您的类型可以实现 `Copy`,则应该这样做。 但是请记住,实现 `Copy` 是您类型的公共 API 的一部分。 如果该类型将来可能变为非 `Copy`,则最好现在省略 `Copy` 实现,以避免 API 发生重大更改。 131 | 132 | ### 其他实现者 133 | 134 | 除下面列出的实现者外,以下类型还实现 `Copy`: 135 | 136 | - 函数项类型 (即,为每个函数定义的不同类型) 137 | - 函数指针类型 (例如 `fn() -> i32`) 138 | - 如果项类型也实现 `Copy` (例如 `[i32; 123456]`),则所有大小的数组类型 139 | - 如果每个组件还实现 `Copy` (例如 `()`,`(i32, bool)`),则为元组类型 140 | - 闭包类型,如果它们没有从环境中捕获任何值,或者所有此类捕获的值本身都实现了 `Copy`。 请注意,由共享引用捕获的变量始终实现 `Copy` (即使引用对象没有实现),而由变量引用捕获的变量从不实现 `Copy`。 141 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/send/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Send trait" 3 | linkTitle: "Send trait" 4 | weight: 1340 5 | date: 2021-12-01 6 | description: > 7 | 可以跨线程边界传输的类型。 8 | --- 9 | 10 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/send/rust-bczd.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "[Rust编程之道笔记]Send trait" 3 | linkTitle: "[Rust编程之道笔记]" 4 | weight: 1344 5 | date: 2021-12-01 6 | description: > 7 | Rust编程之道一书 3.4.4 标签trait 8 | --- 9 | 10 | rust 提供了 Send 和 Sync 两个标签 trait,他们是 rust 无数据竞争并发的基石。 11 | 12 | - 实现了 Send 的类型,可以安全的在线程间传递值,也就是说可以跨线程传递所有权 13 | - 实现了 Sync 的类型,可以跨线程安全地传递共享(不可变)引用 14 | 15 | 有了这两个标签,就可以把rust中所有的类型归为两类: 16 | 17 | 1. 可以安全跨线程传递的值和引用 18 | 2. 不可以安全跨线程传递的值和引用 19 | 20 | 在配合所有权机制,带来的效果就是,rust 能够在编译期就检查出数据竞争的隐患,而不需要到运行时再排查。 21 | 22 | 23 | 24 | ```rust 25 | # 备注:这行代码在 marker.rs 中已经找不到了,不知道 26 | # 为所有类型实现 Send 27 | unsafe impl Send for .. {} 28 | 29 | #[stable(feature = "rust1", since = "1.0.0")] 30 | # 使用 !Send 语法排除 *const T 和 *mut T 31 | impl !Send for *const T {} 32 | #[stable(feature = "rust1", since = "1.0.0")] 33 | impl !Send for *mut T {} 34 | ``` 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/send/source.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Send trait的源码" 3 | linkTitle: "源码" 4 | weight: 1334 5 | date: 2021-12-01 6 | description: > 7 | Send trait的源码 8 | --- 9 | 10 | https://github.com/rust-lang/rust/blob/master/library/core/src/marker.rs 11 | 12 | ```rust 13 | #[stable(feature = "rust1", since = "1.0.0")] 14 | #[cfg_attr(not(test), rustc_diagnostic_item = "send_trait")] 15 | #[rustc_on_unimplemented( 16 | message = "`{Self}` cannot be sent between threads safely", 17 | label = "`{Self}` cannot be sent between threads safely" 18 | )] 19 | pub unsafe auto trait Send { 20 | // empty. 21 | } 22 | 23 | #[stable(feature = "rust1", since = "1.0.0")] 24 | impl !Send for *const T {} 25 | #[stable(feature = "rust1", since = "1.0.0")] 26 | impl !Send for *mut T {} 27 | ``` 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/send/std-doc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Send trait的std文档" 3 | linkTitle: "std文档" 4 | weight: 1342 5 | date: 2021-12-01 6 | description: > 7 | Send trait的std文档 8 | --- 9 | 10 | https://doc.rust-lang.org/std/marker/trait.Send.html 11 | 12 | ```rust 13 | pub unsafe auto trait Send { } 14 | ``` 15 | 16 | 可以跨线程边界传输的类型。 17 | 18 | 当编译器确定适当时,会自动实现此 trait。 19 | 20 | 非 `Send` 类型的一个示例是引用计数指针 [`rc::Rc`](../../std/rc/struct.Rc.html)。 如果两个线程试图克隆指向相同引用计数值的 [`Rc`](../../std/rc/struct.Rc.html),它们可能会同时尝试更新引用计数,这是 [未定义行为](../../reference/behavior-considered-undefined.html) 因为 [`Rc`](../../std/rc/struct.Rc.html) 不使用原子操作。 21 | 22 | 它的表亲 [`sync::Arc`](../../std/sync/struct.Arc.html) 确实使用原子操作 (产生一些开销),因此它是 `Send`。 23 | 24 | 有关更多详细信息,请参见 [the Nomicon](https://doc.rust-lang.org/nomicon/send-and-sync.html)。 25 | 26 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/sized/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Sized trait" 3 | linkTitle: "Sized trait" 4 | weight: 1310 5 | date: 2021-12-01 6 | description: > 7 | Sized trait用于标记在编译时已知常量大小的类型。 8 | --- 9 | 10 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/sized/rust-bczd.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "[Rust编程之道笔记]Sided trait" 3 | linkTitle: "[Rust编程之道笔记]" 4 | weight: 1314 5 | date: 2021-12-01 6 | description: > 7 | Rust编程之道一书 3.4.4 标签trait 8 | --- 9 | 10 | 11 | 12 | Sized trait 非常重要,编译期用它来识别在编译期确定大小的类型。 13 | 14 | ```rust 15 | #[lang = "sized"] 16 | pub trait Sized { 17 | // Empty. 18 | } 19 | ``` 20 | 21 | Sized trait 是空 trait,仅仅作为标签 trait 供编译期使用。真正起"打标签"作用的是属性 `#[lang = "sized"]`。该属性lang表示Sized trait供rust语言本身使用,声明为 "sized",称为语言项(Lang Item)。 22 | 23 | rust语言中大部分类型都是默认 Sized ,如果需要使用动态大小类型,则需要改为 `` 限定。 24 | 25 | ```rust 26 | struct Foo(T); 27 | struct Bar(T); 28 | ``` 29 | 30 | 31 | 32 | ### Sized, Unsize和 ?Sized的关系 33 | 34 | 35 | 36 | - Sized 标记的是在编译期可确定大小的类型 37 | 38 | - Unsized 标记的是动态大小类型,在编译期无法确定其大小 39 | 40 | 目前rust中的动态类型有 trait 和 [T] 41 | 42 | 其中 [T] 代表一定数量的T在内存中的一次排列,但不知道具体的数量,所以大小是未知的。 43 | 44 | - ?Sized 标记的类型包含了 Sized 和 Unsized 所标识的两种类型。 45 | 46 | 所以泛型结构体 `struct Bar(T);` 支持编译期可确定大小类型和动态大小类型两种类型。 47 | 48 | ### 动态大小类型的限制规则 49 | 50 | - 只可以通过胖指针来操作 Unsize 类型,如 `&[T]` 或者 `&trait` 51 | - 变量,参数和枚举变量不能使用动态大小类型 52 | - 结构体中只有最有一个字段可以使用动态大小类型,其他字段不可以使用 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/sized/source.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Sized trait的源码" 3 | linkTitle: "源码" 4 | weight: 1313 5 | date: 2021-12-01 6 | description: > 7 | Sized trait的 8 | --- 9 | 10 | https://github.com/rust-lang/rust/blob/master/library/core/src/marker.rs 11 | 12 | ```rust 13 | #[stable(feature = "rust1", since = "1.0.0")] 14 | #[lang = "sized"] 15 | #[rustc_on_unimplemented( 16 | message = "the size for values of type `{Self}` cannot be known at compilation time", 17 | label = "doesn't have a size known at compile-time" 18 | )] 19 | #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable 20 | #[rustc_specialization_trait] 21 | pub trait Sized { 22 | // Empty. 23 | } 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/sized/std-doc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Sized trait的std文档" 3 | linkTitle: "std文档" 4 | weight: 1312 5 | date: 2021-12-01 6 | description: > 7 | Sized trait的std文档 8 | --- 9 | 10 | https://doc.rust-lang.org/std/marker/trait.Sized.html 11 | 12 | ```rust 13 | pub trait Sized { } 14 | ``` 15 | 16 | 在编译时已知常量大小的类型。 17 | 18 | 所有类型参数的隐含边界均为 `Sized`。如果不合适,可以使用特殊语法 `?Sized` 删除此绑定。 19 | 20 | ```rust 21 | struct Foo(T); 22 | struct Bar(T); 23 | 24 | // struct FooUse(Foo<[i32]>); // 错误:没有为 [i32] 实现大小调整 25 | struct BarUse(Bar<[i32]>); // OK 26 | ``` 27 | 28 | 一个例外是 trait 的隐式 `Self` 类型。 trait 没有隐式 `Sized` 绑定,因为它与 [trait 对象](../../book/ch17-02-trait-objects.html) 不兼容,根据定义,trait 需要与所有可能的实现者一起使用,因此可以为任意大小。 29 | 30 | 尽管 Rust 允许您将 `Sized` 绑定到 trait,但是以后您将无法使用它来形成 trait 对象: 31 | 32 | ```rust 33 | trait Foo { } 34 | trait Bar: Sized { } 35 | 36 | struct Impl; 37 | impl Foo for Impl { } 38 | impl Bar for Impl { } 39 | 40 | let x: &dyn Foo = &Impl; // OK 41 | // let y: &dyn Bar = &Impl; // 错误:无法将 trait `Bar` 创建成对象 42 | ``` 43 | 44 | > 备注:trait object的要求之一就是trait不能是Sized,这也可以作为禁止将某个trait用作trait object的方式 45 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/sync/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Sync trait" 3 | linkTitle: "Sync trait" 4 | weight: 1350 5 | date: 2021-12-01 6 | description: > 7 | 可以在线程之间安全共享引用的类型。 8 | --- 9 | 10 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/sync/source.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Sync trait的源码" 3 | linkTitle: "源码" 4 | weight: 1354 5 | date: 2021-12-01 6 | description: > 7 | Sync trait的源码 8 | --- 9 | 10 | https://github.com/rust-lang/rust/blob/master/library/core/src/marker.rs 11 | 12 | ```rust 13 | #[stable(feature = "rust1", since = "1.0.0")] 14 | #[cfg_attr(not(test), rustc_diagnostic_item = "sync_trait")] 15 | #[lang = "sync"] 16 | #[rustc_on_unimplemented( 17 | message = "`{Self}` cannot be shared between threads safely", 18 | label = "`{Self}` cannot be shared between threads safely" 19 | )] 20 | pub unsafe auto trait Sync { 21 | // Empty 22 | } 23 | 24 | #[stable(feature = "rust1", since = "1.0.0")] 25 | impl !Sync for *const T {} 26 | #[stable(feature = "rust1", since = "1.0.0")] 27 | impl !Sync for *mut T {} 28 | ``` 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/sync/std-doc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Sync trait的std文档" 3 | linkTitle: "std文档" 4 | weight: 1352 5 | date: 2021-12-01 6 | description: > 7 | Sync trait的std文档 8 | --- 9 | 10 | https://doc.rust-lang.org/std/marker/trait.Sync.html 11 | 12 | ```rust 13 | pub unsafe auto trait Sync { } 14 | ``` 15 | 16 | 可以在线程之间安全共享引用的类型。 17 | 18 | 当编译器确定适当时,会自动实现此 trait。 19 | 20 | 精确的定义是:当且仅当 `&T` 是 [`Send`](trait.Send.html) 时,类型 `T` 才是 [`Sync`](trait.Sync.html)。 换句话说,如果在线程之间传递 `&T` 引用时没有 [未定义的行为](../../reference/behavior-considered-undefined.html) (包括数据竞争) 的可能性。 21 | 22 | 正如人们所料,像 [`u8`](../primitive.u8.html) 和 [`f64`](../primitive.f64.html) 这样的原始类型都是 [`Sync`](trait.Sync.html),包含它们的简单聚合类型也是如此,比如元组、结构体和枚举。 基本 [`Sync`](trait.Sync.html) 类型的更多示例包括不可变类型 (例如 `&T`) 以及具有简单继承的可变性的类型,例如 [`Box`](../../std/boxed/struct.Box.html),[`Vec`](../../std/vec/struct.Vec.html) 和大多数其他集合类型。 23 | 24 | (泛型参数必须为 [`Sync`](trait.Sync.html),容器才能 [[Sync](trait.Sync.html)]。) 25 | 26 | 该定义的一个令人惊讶的结果是 `&mut T` 是 `Sync` (如果 `T` 是 `Sync`),即使看起来可能提供了不同步的可变的。 诀窍是,共享引用 (即 `& &mut T`) 后面的可变引用将变为只读,就好像它是 `& &T` 一样。 因此,没有数据竞争的风险。 27 | 28 | 不是 `Sync` 的类型是具有非线程安全形式的 “内部可变性” 的类型,例如 [`Cell`](../cell/struct.Cell.html) 和 [`RefCell`](../cell/struct.RefCell.html)。 这些类型甚至允许通过不可变,共享引用来更改其内容。 例如,[`Cell`](../cell/struct.Cell.html) 上的 `set` 方法采用 `&self`,因此它仅需要共享的引用 [`&Cell`](../cell/struct.Cell.html)。 该方法不执行同步,因此 [`Cell`](../cell/struct.Cell.html) 不能为 `Sync`。 29 | 30 | 另一个非 `Sync` 类型的例子是引用计数指针 [`Rc`](../../std/rc/struct.Rc.html)。 给定任何引用 [`&Rc`](../../std/rc/struct.Rc.html),您可以克隆新的 [`Rc`](../../std/rc/struct.Rc.html),以非原子方式修改引用计数。 31 | 32 | 对于确实需要线程安全的内部可变性的情况,Rust 提供 [原子数据类型](../sync/atomic/index.html) 以及通过 [`sync::Mutex`](../../std/sync/struct.Mutex.html) 和 [`sync::RwLock`](../../std/sync/struct.RwLock.html) 进行的显式锁定。 这些类型可确保任何可变的都不会引起数据竞争,因此类型为 `Sync`。 同样,[`sync::Arc`](../../std/sync/struct.Arc.html) 提供了 [`Rc`](../../std/rc/struct.Rc.html) 的线程安全模拟。 33 | 34 | 任何具有内部可变性的类型还必须在 value(s) 周围使用 [`cell::UnsafeCell`](../cell/struct.UnsafeCell.html) 包装器,该包装器可以通过共享的引用进行更改。 [未定义的行为](../../reference/behavior-considered-undefined.html) 无法做到这一点。 例如,从 `&T` 到 `&mut T` 的 [`transmute`](../mem/fn.transmute.html) 无效。 35 | 36 | 有关 `Sync` 的更多详细信息,请参见 [the Nomicon](https://doc.rust-lang.org/nomicon/send-and-sync.html)。 37 | 38 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/unpin/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Unpin trait" 3 | linkTitle: "Unpin trait" 4 | weight: 1360 5 | date: 2021-12-01 6 | description: > 7 | 固定后可以安全移动的类型。 8 | --- 9 | 10 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/unpin/source.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Unpin trait的源码" 3 | linkTitle: "源码" 4 | weight: 1363 5 | date: 2021-12-01 6 | description: > 7 | Unpin trait的源码 8 | --- 9 | 10 | https://github.com/rust-lang/rust/blob/master/library/core/src/marker.rs 11 | 12 | ```rust 13 | #[stable(feature = "pin", since = "1.33.0")] 14 | #[rustc_on_unimplemented( 15 | note = "consider using `Box::pin`", 16 | message = "`{Self}` cannot be unpinned" 17 | )] 18 | #[lang = "unpin"] 19 | pub auto trait Unpin {} 20 | 21 | 22 | /// A marker type which does not implement `Unpin`. 23 | /// 24 | /// If a type contains a `PhantomPinned`, it will not implement `Unpin` by default. 25 | #[stable(feature = "pin", since = "1.33.0")] 26 | #[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] 27 | pub struct PhantomPinned; 28 | 29 | #[stable(feature = "pin", since = "1.33.0")] 30 | impl !Unpin for PhantomPinned {} 31 | 32 | #[stable(feature = "pin", since = "1.33.0")] 33 | impl<'a, T: ?Sized + 'a> Unpin for &'a T {} 34 | 35 | #[stable(feature = "pin", since = "1.33.0")] 36 | impl<'a, T: ?Sized + 'a> Unpin for &'a mut T {} 37 | 38 | #[stable(feature = "pin_raw", since = "1.38.0")] 39 | impl Unpin for *const T {} 40 | 41 | #[stable(feature = "pin_raw", since = "1.38.0")] 42 | impl Unpin for *mut T {} 43 | ``` 44 | 45 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/unpin/std-doc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Unsize trait的std文档" 3 | linkTitle: "std文档" 4 | weight: 1322 5 | date: 2021-12-01 6 | description: > 7 | Unsize trait的std文档 8 | --- 9 | 10 | https://doc.rust-lang.org/std/marker/trait.Unpin.html 11 | 12 | ```rust 13 | pub auto trait Unpin { } 14 | ``` 15 | 16 | 固定后可以安全移动的类型。 17 | 18 | Rust 本身没有固定类型的概念,并认为 move (例如,通过赋值或 `mem::replace` 始终是安全的。 19 | 20 | `Pin` 类型代替使用,以防止在类型系统中移动。`Pin>` 包装器中包裹的指针 `P` 不能移出。 有关固定的更多信息,请参见 `pin` module 文档。 21 | 22 | 为 `T` 实现 `Unpin` trait 消除了固定该类型的限制,然后允许使用诸如 [`mem::replace`](../mem/fn.replace.html) 之类的功能将 `T` 从 `Pin>` 中移出。 23 | 24 | `Unpin` 对于非固定数据完全没有影响。 特别是,[`mem::replace`](../mem/fn.replace.html) 可以愉快地移动 `!Unpin` 数据 (它适用于任何 `&mut T`,而不仅限于 `T: Unpin`)。 但是,您不能对包装在 `Pin>` 内的数据使用 [`mem::replace`](../mem/fn.replace.html),因为您无法获得所需的 `&mut T`,并且 *that* 是使此系统正常工作的原因。 25 | 26 | 因此,例如,这只能在实现 `Unpin` 的类型上完成: 27 | 28 | ```rust 29 | use std::mem; 30 | use std::pin::Pin; 31 | 32 | let mut string = "this".to_string(); 33 | let mut pinned_string = Pin::new(&mut string); 34 | 35 | // 我们需要一个可变引用来调用 `mem::replace`。 36 | // 我们可以通过 (implicitly) 调用 `Pin::deref_mut` 来获得这样的引用,但这仅是可能的,因为 `String` 实现了 `Unpin`。 37 | mem::replace(&mut *pinned_string, "other".to_string()); 38 | ``` 39 | 40 | trait 几乎针对每种类型自动实现。 41 | 42 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/unsized/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Unsized trait" 3 | linkTitle: "Unsized trait" 4 | weight: 1320 5 | date: 2021-12-01 6 | description: > 7 | 可以是未定义大小的类型也可以是动态大小的类型。 8 | --- 9 | 10 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/unsized/source.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Unsize trait的源码" 3 | linkTitle: "源码" 4 | weight: 1323 5 | date: 2021-12-01 6 | description: > 7 | Unsize trait的源码 8 | --- 9 | 10 | https://github.com/rust-lang/rust/blob/master/library/core/src/marker.rs 11 | 12 | ```rust 13 | #[unstable(feature = "unsize", issue = "27732")] 14 | #[lang = "unsize"] 15 | pub trait Unsize { 16 | // Empty. 17 | } 18 | ``` 19 | 20 | -------------------------------------------------------------------------------- /content/zh-cn/std/marker/unsized/std-doc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Unsize trait的std文档" 3 | linkTitle: "std文档" 4 | weight: 1322 5 | date: 2021-12-01 6 | description: > 7 | Unsize trait的std文档 8 | --- 9 | 10 | https://doc.rust-lang.org/std/marker/trait.Unsize.html 11 | 12 | ```rust 13 | pub trait Unsize {} 14 | ``` 15 | 16 | 可以是未定义大小的类型也可以是动态大小的类型。 17 | 18 | 例如,按大小排列的数组类型 `[i8; 2]` 实现 `Unsize<[i8]>` 和 `Unsize`。 19 | 20 | `Unsize` 的所有实现均由编译器自动提供。 21 | 22 | `Unsize` 为以下目的实现: 23 | 24 | - `[T; N]` 是 `Unsize<[T]>` 25 | 26 | - 当`T: Trait` 时 `T` 为 `Unsize` 27 | 28 | - `Foo<..., T, ...>` 是 `Unsize>`,如果 29 | - `T: Unsize` 30 | - Foo 是一个结构体 31 | - 仅 `Foo` 的最后一个字段具有涉及 `T` 的类型 32 | - `T` 不属于任何其他字段的类型 33 | - `Bar: Unsize>`, 如果 `Foo` 的最后一个字段的类型为 `Bar` 34 | 35 | `Unsize` 与 `ops::CoerceUnsized` 一起使用可允许 “user-defined” 容器 (例如 `Rc` 包含动态大小的类型。 有关更多详细信息,请参见 [DST coercion RFC](https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md) 和 [the nomicon entry on coercion](https://doc.rust-lang.org/nomicon/coercions.html)。 36 | 37 | -------------------------------------------------------------------------------- /content/zh-cn/std/result/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的结果(result)" 4 | linkTitle: "结果(result)" 5 | weight: 1200 6 | date: 2021-04-02 7 | description: Rust标准库中的结果(result) 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /content/zh-cn/std/result/result.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的结果(result)介绍" 4 | linkTitle: "结果(result)介绍" 5 | weight: 1201 6 | date: 2021-04-02 7 | description: Rust标准库中的结果(result)介绍 8 | --- 9 | 10 | https://doc.rust-lang.org/std/result/index.html 11 | 12 | 使用Result类型的错误处理。 13 | 14 | Result是用于返回和传播错误的类型。它是一个枚举,其中Ok(T)代表成功并包含一值,Err(E)代表错误并包含错误值。 15 | 16 | ```rust 17 | enum Result { 18 | Ok(T), 19 | Err(E), 20 | } 21 | ``` 22 | 23 | 函数在预计到错误并可恢复时返回Result。在 std crate 中,Result 最显著的作用是用于 I/O。 24 | 25 | 一个简单的返回Result的函数可以这样定义和使用: 26 | 27 | ```rust 28 | #[derive(Debug)] 29 | enum Version { Version1, Version2 } 30 | 31 | fn parse_version(header: &[u8]) -> Result { 32 | match header.get(0) { 33 | None => Err("invalid header length"), 34 | Some(&1) => Ok(Version::Version1), 35 | Some(&2) => Ok(Version::Version2), 36 | Some(_) => Err("invalid version"), 37 | } 38 | } 39 | 40 | let version = parse_version(&[1, 2, 3, 4]); 41 | match version { 42 | Ok(v) => println!("working with version: {:?}", v), 43 | Err(e) => println!("error parsing header: {:?}", e), 44 | } 45 | ``` 46 | 47 | 在Result上的模式匹配对于简单的案例来说是很清晰和直接的,但是Result自带的一些方便的方法可以让工作更简洁。 48 | 49 | ```rust 50 | let good_result: Result = Ok(10); 51 | let bad_result: Result = Err(10); 52 | 53 | // The `is_ok` and `is_err` methods do what they say. 54 | assert!(good_result.is_ok() && !good_result.is_err()); 55 | assert!(bad_result.is_err() && !bad_result.is_ok()); 56 | 57 | // `map` consumes the `Result` and produces another. 58 | let good_result: Result = good_result.map(|i| i + 1); 59 | let bad_result: Result = bad_result.map(|i| i - 1); 60 | 61 | // Use `and_then` to continue the computation. 62 | let good_result: Result = good_result.and_then(|i| Ok(i == 11)); 63 | 64 | // Use `or_else` to handle the error. 65 | let bad_result: Result = bad_result.or_else(|i| Ok(i + 20)); 66 | 67 | // Consume the result and return the contents with `unwrap`. 68 | let final_awesome_result = good_result.unwrap(); 69 | ``` 70 | 71 | ### 结果必须使用 72 | 73 | 使用返回值来表示错误,一个常见的问题是很容易忽略返回值,从而无法处理错误。Result被注释了 #[must_use] 属性,当忽略了Result值时,编译器会发出警告。这使得Result对于可能会遇到错误但不会返回有用值的函数特别有用。 74 | 75 | 考虑一下Write属性为I/O类型定义的write_all方法。 76 | 77 | ```rust 78 | use std::io; 79 | 80 | trait Write { 81 | fn write_all(&mut self, bytes: &[u8]) -> Result<(), io::Error>; 82 | } 83 | ``` 84 | 85 | 注意:Write的实际定义使用的是io::Result,它只是Result的同义词。 86 | 87 | 这个方法不会产生一个值,但是写的时候可能会失败。关键是要处理好错误的情况,不要这样写: 88 | 89 | ```rust 90 | use std::fs::File; 91 | use std::io::prelude::*; 92 | 93 | let mut file = File::create("valuable_data.txt").unwrap(); 94 | // If `write_all` errors, then we'll never know, because the return 95 | // value is ignored. 96 | file.write_all(b"important message"); 97 | ``` 98 | 99 | 如果你真的在Rust中写了,编译器会给你一个警告(默认情况下,由 unused_must_use lint 控制)。 100 | 101 | 相反,如果你不想处理这个错误,你可以直接用 expect 来断言成功。如果写入失败了,这将会panic,并提供一个略微有用的消息来说明原因。 102 | 103 | ```rust 104 | use std::fs::File; 105 | use std::io::prelude::*; 106 | 107 | let mut file = File::create("valuable_data.txt").unwrap(); 108 | file.write_all(b"important message").expect("failed to write message"); 109 | ``` 110 | 111 | 也可以简单地断言成功: 112 | 113 | ``` 114 | assert!(file.write_all(b"important message").is_ok()); 115 | ``` 116 | 117 | 或者使用 `?` 将错误传播到调用栈上: 118 | 119 | ```rust 120 | fn write_message() -> io::Result<()> { 121 | let mut file = File::create("valuable_data.txt")?; 122 | file.write_all(b"important message")?; 123 | Ok(()) 124 | } 125 | ``` 126 | 127 | ### 问号运算符? 128 | 129 | 当编写调用许多返回结果类型的函数的代码时,错误处理可能会很繁琐。问号操作符 `?` 隐藏了一些在调用堆栈中传播错误的繁文缛节。 130 | 131 | 下面这段代码: 132 | 133 | ```rust 134 | use std::fs::File; 135 | use std::io::prelude::*; 136 | use std::io; 137 | 138 | struct Info { 139 | name: String, 140 | age: i32, 141 | rating: i32, 142 | } 143 | 144 | fn write_info(info: &Info) -> io::Result<()> { 145 | // Early return on error 146 | let mut file = match File::create("my_best_friends.txt") { 147 | Err(e) => return Err(e), 148 | Ok(f) => f, 149 | }; 150 | if let Err(e) = file.write_all(format!("name: {}\n", info.name).as_bytes()) { 151 | return Err(e) 152 | } 153 | if let Err(e) = file.write_all(format!("age: {}\n", info.age).as_bytes()) { 154 | return Err(e) 155 | } 156 | if let Err(e) = file.write_all(format!("rating: {}\n", info.rating).as_bytes()) { 157 | return Err(e) 158 | } 159 | Ok(()) 160 | } 161 | ``` 162 | 163 | 将被替代为: 164 | 165 | ```rust 166 | use std::fs::File; 167 | use std::io::prelude::*; 168 | use std::io; 169 | 170 | struct Info { 171 | name: String, 172 | age: i32, 173 | rating: i32, 174 | } 175 | 176 | fn write_info(info: &Info) -> io::Result<()> { 177 | let mut file = File::create("my_best_friends.txt")?; 178 | // Early return on error 179 | file.write_all(format!("name: {}\n", info.name).as_bytes())?; 180 | file.write_all(format!("age: {}\n", info.age).as_bytes())?; 181 | file.write_all(format!("rating: {}\n", info.rating).as_bytes())?; 182 | Ok(()) 183 | } 184 | ``` 185 | 186 | 这样就好很多了! 187 | 188 | 以 ? 结束的表达式将导致成功(Ok)值的 unwrap,除非结果是Err,在这种情况下,Err会从包围函数中提前返回。 189 | 190 | ?只能用于返回 Result 的函数中,因为它提供了 Err 的提前返回。 191 | 192 | ## Result Enum 193 | 194 | ```rust 195 | #[must_use = "this `Result` may be an `Err` variant, which should be handled"] 196 | pub enum Result { 197 | Ok(T), 198 | Err(E), 199 | } 200 | ``` 201 | 202 | Result是一种类型,代表成功(Ok)或失败(Err)。 203 | 204 | 变量: 205 | 206 | - Ok(T): 包含成功值 207 | - Err(E):包含错误值 208 | 209 | ### map_or 方法 210 | 211 | 对包含的值(如果有的话)应用一个函数,或者返回提供的默认值(如果没有的话)。 212 | 213 | 传递给map_or的参数会被立即求值;如果你传递的是函数调用的结果,建议使用map_or_else,它是延迟求值。 214 | 215 | ```rust 216 | let x: Result<_, &str> = Ok("foo"); 217 | assert_eq!(x.map_or(42, |v| v.len()), 3); 218 | 219 | let x: Result<&str, _> = Err("bar"); 220 | assert_eq!(x.map_or(42, |v| v.len()), 42); 221 | ``` 222 | 223 | ### map_or_else方法 224 | 225 | 通过将一个结果映射到U,通过将一个函数应用到包含的Ok值,或者将一个fallback函数应用到包含的Err值。 226 | 227 | 这个函数可以用来在处理错误时解包一个成功的结果。 228 | 229 | ```rust 230 | let k = 21; 231 | 232 | let x : Result<_, &str> = Ok("foo"); 233 | assert_eq!(x.map_or_else(|e| k * 2, |v| v.len()), 3); 234 | 235 | let x : Result<&str, _> = Err("bar"); 236 | assert_eq!(x.map_or_else(|e| k * 2, |v| v.len()), 42); 237 | ``` -------------------------------------------------------------------------------- /content/zh-cn/std/std.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库介绍" 4 | linkTitle: "介绍" 5 | weight: 100 6 | date: 2021-04-02 7 | description: > 8 | Rust标准库介绍 9 | --- 10 | 11 | ### 介绍 12 | 13 | https://doc.rust-lang.org/std/ 14 | 15 | Rust语言标准库是让Rust语言开发的软件具备可移植性的基础,它是一组最小的、经过实战检验的共享抽象,适用于更广泛的Rust生态系统。它提供了核心类型,如Vec和Option、类库定义的语言原语操作、标准宏、I/O和多线程等。 16 | 17 | 默认情况下,所有Rust crate都可以使用std。因此,标准库可以在 use 语句中通过路径 std 访问标准库,如 `std:::env`。 18 | 19 | 标准库的内容有: 20 | 21 | - [`std::*` modules / std 模块](https://doc.rust-lang.org/std/#modules) 22 | - [Primitive types / 基本数据类型](https://doc.rust-lang.org/std/#primitives) 23 | - [Standard macros / 标准宏](https://doc.rust-lang.org/std/#macros) 24 | - [The Rust Prelude / Rust语言序幕](https://doc.rust-lang.org/std/prelude/index.html) 25 | 26 | Async std中文文档 27 | 28 | https://learnku.com/docs/rust-async-std/translation-notes/7132 29 | 30 | sync: 31 | 32 | - Arc 33 | - Mutex 34 | 35 | 36 | collections: 37 | 38 | - BTreeMap 39 | - HashMap 40 | 41 | 42 | 其他内容: 43 | 44 | ```rust 45 | #[derive(Debug, Clone)] 46 | ``` 47 | 48 | -------------------------------------------------------------------------------- /content/zh-cn/std/sync/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的同步" 4 | linkTitle: "同步" 5 | weight: 300 6 | date: 2021-04-02 7 | description: Rust标准库中的同步 8 | --- -------------------------------------------------------------------------------- /content/zh-cn/std/sync/arc.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的原子引用计数(Arc)" 4 | linkTitle: "原子引用计数(Arc)" 5 | weight: 320 6 | date: 2021-04-02 7 | description: Rust标准库中的原子引用计数(Arc) 8 | --- 9 | 10 | https://doc.rust-lang.org/std/sync/struct.Arc.html 11 | 12 | 线程安全的引用计数指针。'Arc'代表 "Atomically Reference Counted/原子引用计数"。 13 | 14 | 类型 Arc 提供了一个 T 类型值的共享所有权,在堆中分配。在Arc上调用clone会产生一个新的Arc实例,它指向与源Arc相同的堆上的分配值,同时增加一个引用计数。当给定分配的最后一个Arc指针被销毁时,存储在该分配中的值(通常被称为 "内部值")也会被丢弃。 15 | 16 | Rust中的共享引用默认不允许改变,Arc也不例外:一般情况下,你无法获得Arc内部的东西的可变引用。如果你需要通过Arc进行改变,请使用Mutex、RwLock或Atomic类型。 17 | 18 | ### 线程安全 19 | 20 | 与 Rc 不同的是,Arc使用原子操作进行引用计数。这意味着它是线程安全的。缺点是,原子操作比普通内存访问更昂贵。如果你不在线程之间共享引用计数的分配,可以考虑使用Rc来降低开销。Rc是一个安全的默认值,因为编译器会捕捉到任何线程之间发送Rc的尝试。但是,为了给库的用户提供更多的灵活性,库可能会选择Arc。 21 | 22 | 只要T实现了Send和Sync,Arc就会实现Send和Sync。为什么不能把一个非线程安全类型的T放在Arc中,使其成为线程安全的呢?一开始可能会觉得有点反直觉:毕竟Arc的重点不就是线程安全吗?关键是这样的。Arc使同一数据有多个所有权的线程安全,但它并没有给它的数据增加线程安全。考虑一下 `Arc>`。RefCell不是Sync,如果Arc总是Send,那么`Arc`也会是Send。但这样一来,我们就有问题了。RefCell不是线程安全的;它使用非原子操作来跟踪借数。 23 | 24 | 最后,这意味着你可能需要将Arc与某种类型的std:::同步类型配对,通常是Mutex。 25 | 26 | ### 用 weak 打破循环 27 | 28 | downgrade方法可以用来创建一个无主的Weak指针。Weak指针可以升级为Arc,但是如果存储在分配中的值已经被降级,则会返回None。换句话说,Weak指针不会使分配中的值保持活的,但是,它们会使分配(值的后备存储)保持活的。 29 | 30 | Arc指针之间的循环永远不会被dealocated。基于这个原因,Weak被用来打破循环。例如,一棵树可以有从父节点到子节点的强Arc指针,而从子节点回到父节点的弱指针。 -------------------------------------------------------------------------------- /content/zh-cn/std/sync/barrier.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的屏障(Barrier)" 4 | linkTitle: "屏障(Barrier)" 5 | weight: 330 6 | date: 2021-04-02 7 | description: Rust标准库中的屏障(Barrier) 8 | --- 9 | 10 | https://doc.rust-lang.org/std/sync/struct.Barrier.html 11 | 12 | Barrier/屏障可以让多个线程同步开始某些计算。 13 | 14 | ```rust 15 | use std::sync::{Arc, Barrier}; 16 | use std::thread; 17 | 18 | let mut handles = Vec::with_capacity(10); 19 | let barrier = Arc::new(Barrier::new(10)); 20 | for _ in 0..10 { 21 | let c = barrier.clone(); 22 | // The same messages will be printed together. 23 | // You will NOT see any interleaving. 24 | handles.push(thread::spawn(move|| { 25 | println!("before wait"); 26 | c.wait(); 27 | println!("after wait"); 28 | })); 29 | } 30 | // Wait for other threads to finish. 31 | for handle in handles { 32 | handle.join().unwrap(); 33 | } 34 | ``` 35 | 36 | ### new 方法 37 | 38 | ```rust 39 | use std::sync::Barrier; 40 | 41 | let barrier = Barrier::new(10); 42 | ``` 43 | 44 | 创建一个新的屏障,可以阻止给定数量的线程。 45 | 46 | 屏障将阻止n-1个线程调用等待,然后当第n个线程调用等待时,立即唤醒所有线程。 47 | 48 | ### wait 方法 49 | 50 | 屏蔽当前线程,直到所有线程在这里会合。 51 | 52 | Barrier在所有线程会合后可以重复使用,并且可以连续使用。 53 | 54 | 单个(任意)线程在从这个函数返回时,会收到一个 is_leader返回 true 的 BarrierWaitResult,其他所有线程都会收到is_leader返回false的结果。 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /content/zh-cn/std/sync/condvar.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的条件变量(Condvar)" 4 | linkTitle: "条件变量(Condvar)" 5 | weight: 340 6 | date: 2021-04-02 7 | description: Rust标准库中的条件变量(Condvar) 8 | --- 9 | 10 | https://doc.rust-lang.org/std/sync/struct.Condvar.html 11 | 12 | 条件变量 13 | 14 | 条件变量代表阻止线程的能力,使其在等待事件发生时不消耗CPU时间。条件变量通常与布尔谓词(一个条件/condition)和mutex关联。在确定线程必须阻止之前,该谓词总是在mutex内部进行验证。 15 | 16 | 这个模块中的函数将阻止当前线程的执行,并尽可能地绑定到系统提供的条件变量。注意,这个模块对系统条件变量有一个额外的限制:每个condvar在运行时只能使用一个mutex。任何试图在同一个条件变量上使用多个mutexes的行为都会导致运行时的恐慌。如果不希望这样,那么sys中的不安全基元就没有这个限制,但可能会导致未定义的行为。 17 | 18 | ```rust 19 | use std::sync::{Arc, Mutex, Condvar}; 20 | use std::thread; 21 | 22 | let pair = Arc::new((Mutex::new(false), Condvar::new())); 23 | let pair2 = pair.clone(); 24 | 25 | // Inside of our lock, spawn a new thread, and then wait for it to start. 26 | thread::spawn(move|| { 27 | let (lock, cvar) = &*pair2; 28 | let mut started = lock.lock().unwrap(); 29 | *started = true; 30 | // We notify the condvar that the value has changed. 31 | cvar.notify_one(); 32 | }); 33 | 34 | // Wait for the thread to start up. 35 | let (lock, cvar) = &*pair; 36 | let mut started = lock.lock().unwrap(); 37 | while !*started { 38 | started = cvar.wait(started).unwrap(); 39 | } 40 | ``` 41 | 42 | ### wait-while方法 43 | 44 | 阻止当前线程,直到这个条件变量收到通知,并且提供的条件为false。 45 | 46 | 这个函数将原子化地解锁指定的mutex(用 guard 表示),并阻塞当前线程。这意味着,任何在mutex解锁后逻辑上发生的notify_one或notify_all的调用都是唤醒这个线程的候选函数。当这个函数调用返回时,指定的锁将被重新获得。 47 | 48 | ```rust 49 | // Wait for the thread to start up. 50 | let (lock, cvar) = &*pair; 51 | // As long as the value inside the `Mutex` is `true`, we wait. 52 | let _guard = cvar.wait_while(lock.lock().unwrap(), |pending| { *pending }).unwrap(); 53 | ``` -------------------------------------------------------------------------------- /content/zh-cn/std/sync/mpsc.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的多生产者单消费者队列(mpsc)" 4 | linkTitle: "多生产者单消费者队列(mpsc)" 5 | weight: 350 6 | date: 2021-04-02 7 | description: Rust标准库中的多生产者单消费者队列(mpsc) 8 | --- 9 | 10 | https://doc.rust-lang.org/std/sync/mpsc/index.html 11 | 12 | 多生产者、单消费者FIFO队列通信原语。 13 | 14 | mpsc = Multiple Producer Single Consumer 15 | 16 | 该模块提供在通道(channel)上基于消息的通信,具体定义为三种类型。 17 | 18 | - Sender 19 | - SyncSender 20 | - Receiver 21 | 22 | Sender 或 SyncSender 用于向 Receiver 发送数据。这两个 sender 都是可克隆的(多生产者),这样,许多线程可以同时向一个 Receiver 发送数据(单消费者)。 23 | 24 | 这些通道(channel)有两种类型。 25 | 26 | 1. 异步的、无限缓冲的通道(channel)。channel 函数将返回一个(Sender, Receiver)元组,其中所有的发送都是异步的(它们从不阻塞)。该通道在概念上有一个无限缓冲。 27 | 28 | 2. 同步的、有边界的通道(channel)。sync_channel 函数将返回一个(SyncSender, Receiver) tuple,在这个函数中,等待消息的存储是一个预先分配的固定大小的缓冲区。所有的发送都将通过阻塞来同步,直到有可用的缓冲区空间。请注意,允许边界为0,这将使该通道成为一个 "会合 "通道,每个发送方都会将消息原子化地交给接收方。 29 | 30 | ### 断连 31 | 32 | 通道上的发送和接收操作都会返回一个结果,表示操作是否成功。一个不成功的操作通常表示一个通道的另一半通道被丢弃在相应的线程中而 "挂断"。 33 | 34 | 一旦一个通道的一半被deocallated,大多数操作就不能再继续进行,所以会返回Err。许多应用程序会继续解包这个模块返回的结果,如果其中一个线程意外死亡,就会在线程之间传播失败。 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /content/zh-cn/std/sync/mutex.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的互斥(Mutex)" 4 | linkTitle: "互斥(Mutex)" 5 | weight: 360 6 | date: 2021-04-02 7 | description: Rust标准库中的互斥(Mutex) 8 | --- 9 | 10 | https://doc.rust-lang.org/std/sync/struct.Mutex.html 11 | 12 | 用于保护共享数据的互斥原语 13 | 14 | 这个mutex将阻止等待锁可用的线程。mutex也可以被静态初始化或通过 new 构造函数创建。每个mutex都有一个 type 参数,表示它所保护的数据。这些数据只能通过 lock 和 try_lock 返回的 RAII 守护来访问,这保证了只有当mutex被锁定时,数据才会被访问。 15 | 16 | ### 毒化/Poisoning 17 | 18 | 这个模块中的 mutex 实现了一种叫做 " poisoning "的策略,每当持有 mutex 的线程恐慌时,就会认为 mutex 中毒。一旦 mutex 被毒化,所有其他线程都无法默认访问该数据,因为它很可能被污染了(某些不变性没有被维护)。 19 | 20 | 对于mutex来说,这意味着 lock 和 try_lock 方法会返回一个Result值,表示mutex是否被毒化。大多数使用mutex的方法都会简单地将这些结果 unwrap(),在线程之间传播恐慌,以确保不会出现可能无效的变量。 21 | 22 | 然而,被毒化的 mutex 并不会阻止对底层数据的所有访问。PoisonError 类型有一个 into_inner 方法,它将返回在成功锁定时返回的守护。这样,尽管锁被毒化了,但仍然可以访问数据。 23 | 24 | ### new方法 25 | 26 | 在解锁状态下创建一个新的mutex,可以随时使用。 27 | 28 | ``` 29 | pub fn new(t: T) -> Mutex 30 | 31 | use std::sync::Mutex; 32 | 33 | let mutex = Mutex::new(0); 34 | ``` 35 | 36 | ### lock方法 37 | 38 | 获取一个mutex,阻塞当前线程,直到它能够这样做。 39 | 40 | 这个函数将阻塞本地线程,直到它可以获取mutex为止。返回后,该线程是唯一一个持有锁的线程。返回一个RAII守护,允许范围化解锁。当保护罩超出范围时,mutex将被解锁。 41 | 42 | 在已经持有锁的线程中锁定一个mutex的确切行为没有说明。但是,这个函数在第二次调用时不会返回(例如,它可能会出现恐慌或死锁)。 43 | 44 | ### try_lock方法 45 | 46 | 尝试获取此锁。 47 | 48 | 如果此时无法获得该锁,则返回Err。否则,将返回一个RAII护卫。当护卫被丢弃时,该锁将被解锁。 49 | 50 | 此功能不阻塞。 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /content/zh-cn/std/sync/once.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的一次性(Once)" 4 | linkTitle: "一次性(Once)" 5 | weight: 370 6 | date: 2021-04-02 7 | description: Rust标准库中的一次性(Once) 8 | --- 9 | 10 | https://doc.rust-lang.org/std/sync/struct.Once.html 11 | 12 | 一个同步原语,可用于运行一次性全局初始化。用于FFI或相关功能的一次性初始化。这种类型只能用 Once:::new 构造函数构造。 13 | 14 | ### call_once 方法 15 | 16 | 执行初始化例程一次,并且只执行一次。如果这是 call_once 第一次被调用,给定的闭包将被执行,否则不会调用该例程。 17 | 18 | 如果当前有另一个初始化例程正在运行,该方法将阻止调用的线程。 19 | 20 | 当这个函数返回时,保证一些初始化已经运行并完成(可能不是指定的闭包)。它还保证由执行的闭包所执行的任何内存写入都能被其他线程在这时可靠地观察到(闭包和返回后执行的代码之间存在着发生前的关系)。 21 | 22 | 如果给定的闭包在同一个 Once 实例上递归调用 call_once,则没有指定确切的行为,允许的结果是恐慌或死锁。 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /content/zh-cn/std/sync/rwlock.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的读写锁(RwLock)" 4 | linkTitle: "读写锁(RwLock)" 5 | weight: 380 6 | date: 2021-04-02 7 | description: Rust标准库中的读写锁(RwLock) 8 | --- 9 | 10 | https://doc.rust-lang.org/std/sync/struct.RwLock.html 11 | 12 | 读写锁 13 | 14 | 这种类型的锁允许在任何时间点上有多个读或最多一个写。这种锁的写部分通常允许修改底层数据(独占访问),而读部分通常允许只读访问(共享访问)。 15 | 16 | 相比之下,Mutex不区分获取该锁的读写,因此会阻止任何等待该锁可用的线程。RwLock将允许任何数量的读获取该锁,只要一个写不持有该锁。 17 | 18 | 锁的优先级策略取决于底层操作系统的实现,这种类型并不保证会使用任何特定的策略。 19 | 20 | 类型参数T代表这个锁所保护的数据。它要求T满足Send满足跨线程共享和满足Sync以便通过reader并发访问。从锁方法中返回的RAII守护实现了Deref(和写方法的DerefMut),允许访问锁的内容。 21 | 22 | ### 毒化 23 | 24 | 像Mutex一样,RwLock会在恐慌时中毒。但是,请注意,只有在RwLock被完全锁定时(写模式)发生恐慌时,RwLock才会中毒。如果恐慌发生在任何读卡器中,那么该锁将不会中毒。 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /content/zh-cn/std/sync/sync.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的同步介绍" 4 | linkTitle: "介绍" 5 | weight: 301 6 | date: 2021-04-02 7 | description: Rust标准库中的同步介绍 8 | --- 9 | 10 | https://doc.rust-lang.org/std/sync/index.html 11 | 12 | 有用的同步原语。 13 | 14 | ### 同步化的需要 15 | 16 | 从概念上讲,Rust程序是指在计算机上执行的一系列操作。程序中发生事件的时间线与代码中的操作顺序是一致的。 17 | 18 | 考虑一下下面的代码,在一些全局静态变量上进行操作。 19 | 20 | ```rust 21 | static mut A: u32 = 0; 22 | static mut B: u32 = 0; 23 | static mut C: u32 = 0; 24 | 25 | fn main() { 26 | unsafe { 27 | A = 3; 28 | B = 4; 29 | A = A + B; 30 | C = B; 31 | println!("{} {} {}", A, B, C); 32 | C = A; 33 | } 34 | } 35 | ``` 36 | 37 | 看起来好像是改变了一些存储在内存中的变量,进行了一次加法,结果存储在A中,变量C被修改了两次。 38 | 39 | 当只涉及到一个线程时,结果和预期的一样:7 4 4 4行被打印出来。 40 | 41 | 至于幕后会发生什么,当启用优化后,最终生成的机器代码可能会和代码中的样子大不相同。 42 | 43 | - 第一个存储到C的存储可能会被移到A或B之前,就像我们写的C = 4; A = 3; B = 4一样。 44 | 45 | - A+B的赋值可能会被删除,因为和可以存储在一个临时位置,直到它被打印出来,而全局变量永远不会被更新。 46 | 47 | - 最终的结果可以通过在编译时查看代码来确定,所以恒定折叠可能会把整个代码块变成一个简单的println!("7 4 4 4")。 48 | 49 | 编译器可以执行这些优化的任意组合,只要最终优化后的代码在执行时,产生的结果与没有优化的代码相同。 50 | 51 | 由于现代计算机的并发性,对程序执行顺序的假设往往是错误的。对全局变量的访问可能会导致非确定性的结果,即使是在编译器优化被禁用的情况下,仍然有可能引入同步bug。 52 | 53 | 需要注意的是,由于Rust的安全保证,访问全局(静态)变量需要不安全的代码,假设我们没有使用本模块中的任何同步基元,那么访问全局(静态)变量就需要不安全的代码。 54 | 55 | ### 越级执行 56 | 57 | 由于各种原因,指令的执行顺序可能与我们定义的顺序不同。 58 | 59 | - 编译器重排序:如果编译器可以在更早的时候发出指令,它就会尝试这样做。例如,它可能会在代码块的顶部吊起内存负载,这样CPU就可以开始从内存中预取值。 60 | 61 | - 在单线程场景中,当编写信号处理程序或某些类型的低级代码时,这可能会引起问题。使用编译器栅栏来防止这种重新排序。 62 | 63 | - 单个处理器执行指令的顺序失序。现代CPU能够超尺度执行,即可能同时执行多条指令,即使机器代码描述的是一个顺序过程。 64 | 65 | 这种重排序是由CPU透明地处理的。 66 | 67 | - 一个多处理器系统同时执行多个硬件线程的情况。在多线程场景中,可以使用两种基元来处理同步问题。 68 | - 内存栅栏,确保内存访问以正确的顺序被其他CPU看到。 69 | - 二是原子操作,以确保同时访问同一内存位置不会导致非定义行为。 70 | 71 | ## 更高层次的同步对象 72 | 73 | 大多数低级的同步原语都相当容易出错,使用起来也不方便,这也是为什么标准库也暴露了一些更高级别的同步对象的原因。 74 | 75 | 这些抽象对象可以从低级原语中构建出来。为了提高效率,标准库中的同步对象通常是在操作系统内核的帮助下实现的,当线程在获取锁时被阻塞时,内核能够对线程进行重新安排。 76 | 77 | 下面是可用的同步对象的概述: 78 | 79 | - Arc:原子引用计数(Atomically Reference-Counted)指针,可以在多线程环境下使用,以延长某些数据的使用寿命,直到所有线程都使用完为止。 80 | 81 | - Barrier:屏障。确保多个线程相互等待对方到达程序中的某个点,然后再一起继续执行。 82 | 83 | - Condvar:条件变量,提供在等待事件发生时阻止一个线程的能力。 84 | 85 | - mpsc:多生产者,单消费(Multi-producer, single-consumer)队列,用于基于消息的通信。可以提供轻量级的线程间同步机制,代价是增加一些额外的内存。 86 | 87 | - 互斥机制(Mutex)。互斥机制,确保每次最多只有一个线程能够访问一些数据。 88 | 89 | - Once:用于全局变量的线程安全的一次性初始化。 90 | 91 | - RwLock:用于全局变量的初始化。提供了一个相互排斥机制,允许多个读同时访问,同时一次只允许一个写。在某些情况下,这可能比mutex更有效。 92 | 93 | -------------------------------------------------------------------------------- /content/zh-cn/std/thread/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的Thread" 4 | linkTitle: "Thread" 5 | weight: 700 6 | date: 2021-04-02 7 | description: Rust标准库中的Thread 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /content/zh-cn/std/thread/thread.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Rust标准库中的Thread介绍" 4 | linkTitle: "Thread介绍" 5 | weight: 701 6 | date: 2021-04-02 7 | description: Rust标准库中的Thread介绍 8 | --- 9 | 10 | https://doc.rust-lang.org/std/thread/index.html 11 | 12 | 原生线程。 13 | 14 | ### 线程模式 15 | 16 | 一个正在执行的Rust程序由一系列原生操作系统线程组成,每个线程都有自己的堆栈和本地状态。线程可以被命名,并提供一些内置的低级同步支持。 17 | 18 | 线程之间的通信可以通过通道、Rust的消息传递类型以及其他形式的线程同步和共享内存数据结构来完成。特别是,那些被保证为线程安全的类型可以很容易地在线程之间使用原子引用计数容器Arc来共享。 19 | 20 | Rust中的致命逻辑错误会导致线程恐慌,在这一过程中,线程会解开堆栈,运行解析器并释放拥有的资源。虽然Rust中的恐慌并不是作为 "try/catch"机制,但是,Rust中的恐慌还是可以通过catch_unwind来捕获(除非在编译时使用panic=abort)并恢复,或者用 resume_unwind 来恢复。如果 panic没有被捕获,线程就会退出,但是可以选择从不同的线程中用 join 检测到 panic。如果主线程在没有捕获到恐慌的情况下发生恐慌,应用程序将以非零退出代码退出。 21 | 22 | 当Rust程序的主线程终止时,即使其他线程还在运行,整个程序也会关闭。但是,这个模块提供了方便的设施,可以自动等待子线程的终止(即join)。 23 | 24 | ### 生成线程 25 | 26 | 可以使用 thread:::spawn 函数生成一个新的线程。 27 | 28 | ```rust 29 | use std::thread; 30 | 31 | thread::spawn(move || { 32 | // some work here 33 | }); 34 | ``` 35 | 36 | 在这个例子中,生成的线程是与当前线程 "分离 "的。这意味着它可以超过它的父线程(产生它的线程),除非这个父线程是主线程。 37 | 38 | 父线程也可以等待子线程的完成;调用 spawn 会产生 JoinHandle,它提供了一个用于等待的 join 方法。 39 | 40 | ```rust 41 | use std::thread; 42 | 43 | let child = thread::spawn(move || { 44 | // some work here 45 | }); 46 | // some work here 47 | let res = child.join(); 48 | ``` 49 | 50 | join方法返回 thread::Result ,其中包含子线程产生的最终值Ok,如果子线程 panic ,则返回给调用 panic! 的 Err 的值。 51 | 52 | ### 配置线程 53 | 54 | 新的线程可以通过 Builder 类型在产生新的线程之前进行配置,目前可以设置子线程的名称和堆栈大小。 55 | 56 | ```rust 57 | use std::thread; 58 | 59 | thread::Builder::new().name("child1".to_string()).spawn(move || { 60 | println!("Hello, world!"); 61 | }); 62 | ``` 63 | 64 | ### 线程类型 65 | 66 | 线程是通过线程类型来表示的,你可以通过两种方式之一来获得。 67 | 68 | - 通过生成一个新的线程,例如,使用 thread::spawn 函数,并在 JoinHandle上调用 thread。 69 | - 通过使用 thread::current 函数请求当前线程。 70 | 71 | Thread::current 函数即使对于不是通过这个模块的API产生的线程也可以使用。 72 | 73 | ### thread-local存储 74 | 75 | 这个模块还为Rust程序提供了 thread-local 存储的实现。线程本地存储是一种将数据存储到全局变量中的方法,程序中的每个线程都有自己的副本。线程不共享这个数据,所以访问不需要同步。 76 | 77 | 线程-本地键拥有它所包含的值,当线程退出时,将销毁该值。它是用 thread_local! 宏创建的,可以包含任何 `'static` 的值(没有借用指针)。它提供了一个访问器函数 with,可以产生一个共享引用到指定的闭包的值。线程本地键只允许对值进行共享访问,因为如果容许可变借用,就没有办法保证唯一性。大多数值都希望通过Cell或RefCell类型利用某种形式的内部可变性。 78 | 79 | ### 命名线程 80 | 81 | 线程可以有相关的名称,以便于识别。默认情况下,生成的线程是不命名的。要指定一个线程的名称,用Builder构建线程,并将所需的线程名称传递给 Builder::name。要从线程中获取线程名称,使用Thread::name。几个例子说明了线程名称被使用的情况。 82 | 83 | - 如果在一个已命名的线程中发生恐慌,线程名称将被打印在恐慌消息中。 84 | - 线程的名字会被提供给操作系统(例如,在unix-like平台上的pthread_setname_np)。 85 | 86 | ### 栈的大小 87 | 88 | 产生线程的默认堆栈大小为 2 MiB,但这个特定的堆栈大小将来可能会改变。有两种方法可以手动指定生成线程的堆栈大小。 89 | 90 | - 用Builder构建线程,并将所需的堆栈大小传递给 Builder::stack_size。 91 | - 将 RUST_MIN_STACK 环境变量设置为代表所需堆栈大小的整数(单位为字节)。注意,设置Builder::stack_size将覆盖这个值。 92 | 93 | 注意,主线程的堆栈大小不是由Rust决定的。 94 | 95 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | 3 | services: 4 | 5 | site: 6 | image: docsy/docsy-example 7 | build: 8 | context: . 9 | command: server 10 | ports: 11 | - "1313:1313" 12 | volumes: 13 | - .:/src 14 | -------------------------------------------------------------------------------- /docsy.work: -------------------------------------------------------------------------------- 1 | go 1.19 2 | 3 | use . 4 | use ../docsy/ // Local docsy clone resides in sibling folder to this project 5 | // use ./themes/docsy/ // Local docsy clone resides in themes folder 6 | -------------------------------------------------------------------------------- /docsy.work.sum: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/docsy.work.sum -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/google/docsy-example 2 | 3 | go 1.12 4 | 5 | require github.com/google/docsy v0.8.0 // indirect 6 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/FortAwesome/Font-Awesome v0.0.0-20230327165841-0698449d50f2 h1:Uv1z5EqCfmiK4IHUwT0m3h/u/WCk+kpRfxvAZhpC7Gc= 2 | github.com/FortAwesome/Font-Awesome v0.0.0-20230327165841-0698449d50f2/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo= 3 | github.com/google/docsy v0.8.0 h1:RgHyKRTo8YwScMThrf01Ky2yCGpUS1hpkspwNv6szT4= 4 | github.com/google/docsy v0.8.0/go.mod h1:FqTNN2T7pWEGW8dc+v5hQ5VF29W5uaL00PQ1LdVw5F8= 5 | github.com/twbs/bootstrap v5.2.3+incompatible h1:lOmsJx587qfF7/gE7Vv4FxEofegyJlEACeVV+Mt7cgc= 6 | github.com/twbs/bootstrap v5.2.3+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0= 7 | -------------------------------------------------------------------------------- /hugo.toml: -------------------------------------------------------------------------------- 1 | baseURL = "/" 2 | title = "Rust学习笔记" 3 | 4 | # Language settings 5 | contentDir = "content/zh-cn" 6 | defaultContentLanguage = "zh-cn" 7 | defaultContentLanguageInSubdir = false 8 | # Useful when translating. 9 | enableMissingTranslationPlaceholders = true 10 | 11 | enableRobotsTXT = true 12 | 13 | # Will give values to .Lastmod etc. 14 | enableGitInfo = false 15 | 16 | # Comment out to enable taxonomies in Docsy 17 | # disableKinds = ["taxonomy", "taxonomyTerm"] 18 | 19 | # You can add your own taxonomies 20 | [taxonomies] 21 | tag = "tags" 22 | category = "categories" 23 | 24 | [params.taxonomy] 25 | # set taxonomyCloud = [] to hide taxonomy clouds 26 | taxonomyCloud = ["tags", "categories"] 27 | 28 | # If used, must have same length as taxonomyCloud 29 | taxonomyCloudTitle = ["Tag Cloud", "Categories"] 30 | 31 | # set taxonomyPageHeader = [] to hide taxonomies on the page headers 32 | taxonomyPageHeader = ["tags", "categories"] 33 | 34 | 35 | # Highlighting config 36 | pygmentsCodeFences = true 37 | pygmentsUseClasses = false 38 | # Use the new Chroma Go highlighter in Hugo. 39 | pygmentsUseClassic = false 40 | #pygmentsOptions = "linenos=table" 41 | # See https://help.farbox.com/pygments.html 42 | pygmentsStyle = "tango" 43 | 44 | # Configure how URLs look like per section. 45 | [permalinks] 46 | blog = "/:section/:year/:month/:day/:slug/" 47 | 48 | # Image processing configuration. 49 | [imaging] 50 | resampleFilter = "CatmullRom" 51 | quality = 75 52 | anchor = "smart" 53 | 54 | # Language configuration 55 | 56 | [languages] 57 | [languages.zh-cn] 58 | languageName ="中文" 59 | # Weight used for sorting. 60 | weight = 1 61 | [languages.zh-cn.params] 62 | title = "Rust学习笔记" 63 | description = "Rust学习笔记,记录学习Rust的过程和相关资料" 64 | contentDir = "content/zh-cn" 65 | time_format_default = "2006.01.02" 66 | time_format_blog = "2006.01.02" 67 | 68 | [markup] 69 | [markup.goldmark] 70 | [markup.goldmark.parser.attribute] 71 | block = true 72 | [markup.goldmark.renderer] 73 | unsafe = true 74 | [markup.highlight] 75 | # See a complete list of available styles at https://xyproto.github.io/splash/docs/all.html 76 | style = "tango" 77 | # Uncomment if you want your chosen highlight style used for code blocks without a specified language 78 | # guessSyntax = "true" 79 | 80 | # Everything below this are Site Params 81 | 82 | # Comment out if you don't want the "print entire section" link enabled. 83 | [outputs] 84 | section = ["HTML", "print", "RSS"] 85 | 86 | [params] 87 | copyright = "skyao.io" 88 | privacy_policy = "" 89 | 90 | # First one is picked as the Twitter card image if not set on page. 91 | # images = ["images/project-illustration.png"] 92 | 93 | # Menu title if your navbar has a versions selector to access old versions of your site. 94 | # This menu appears only if you have at least one [params.versions] set. 95 | version_menu = "Releases" 96 | 97 | # Flag used in the "version-banner" partial to decide whether to display a 98 | # banner on every page indicating that this is an archived version of the docs. 99 | # Set this flag to "true" if you want to display the banner. 100 | archived_version = false 101 | 102 | # The version number for the version of the docs represented in this doc set. 103 | # Used in the "version-banner" partial to display a version number for the 104 | # current doc set. 105 | version = "0.0" 106 | 107 | # A link to latest version of the docs. Used in the "version-banner" partial to 108 | # point people to the main doc site. 109 | url_latest_version = "https://skyao.io/learning-rust" 110 | 111 | # Repository configuration (URLs for in-page links to opening issues and suggesting changes) 112 | github_repo = "https://github.com/skyao/learning-rust" 113 | # An optional link to a related project repo. For example, the sibling repository where your product code lives. 114 | github_project_repo = "https://github.com/skyao/learning-rust" 115 | 116 | # Specify a value here if your content directory is not in your repo's root directory 117 | # github_subdir = "" 118 | 119 | # Uncomment this if your GitHub repo does not have "main" as the default branch, 120 | # or specify a new value if you want to reference another branch in your GitHub links 121 | github_branch= "main" 122 | 123 | # Google Custom Search Engine ID. Remove or comment out to disable search. 124 | gcs_engine_id = "d3c56aefaae284df1" 125 | # enable google analytics 126 | [services.googleAnalytics] 127 | id = "G-4BVWTNS4MB" 128 | 129 | # Enable Lunr.js offline search 130 | offlineSearch = false 131 | 132 | # Enable syntax highlighting and copy buttons on code blocks with Prism 133 | prism_syntax_highlighting = true 134 | 135 | # User interface configuration 136 | [params.ui] 137 | # Set to true to disable breadcrumb navigation. 138 | breadcrumb_disable = false 139 | # Set to true to disable the About link in the site footer 140 | footer_about_disable = true 141 | # Set to false if you don't want to display a logo (/assets/icons/logo.svg) in the top navbar 142 | navbar_logo = true 143 | # Set to true if you don't want the top navbar to be translucent when over a `block/cover`, like on the homepage. 144 | navbar_translucent_over_cover_disable = false 145 | # Enable to show the side bar menu in its compact state. 146 | sidebar_menu_compact = true 147 | # Set to true to hide the sidebar search box (the top nav search box will still be displayed if search is enabled) 148 | sidebar_search_disable = false 149 | 150 | # Adds a H2 section titled "Feedback" to the bottom of each doc. The responses are sent to Google Analytics as events. 151 | # This feature depends on [services.googleAnalytics] and will be disabled if "services.googleAnalytics.id" is not set. 152 | # If you want this feature, but occasionally need to remove the "Feedback" section from a single page, 153 | # add "hide_feedback: true" to the page's front matter. 154 | [params.ui.feedback] 155 | enable = false 156 | # The responses that the user sees after clicking "yes" (the page was helpful) or "no" (the page was not helpful). 157 | yes = 'Glad to hear it! Please tell us how we can improve.' 158 | no = 'Sorry to hear that. Please tell us how we can improve.' 159 | 160 | # Adds a reading time to the top of each doc. 161 | # If you want this feature, but occasionally need to remove the Reading time from a single page, 162 | # add "hide_readingtime: true" to the page's front matter 163 | [params.ui.readingtime] 164 | enable = false 165 | 166 | [params.plantuml] 167 | enable = true 168 | theme = "default" 169 | #Set url to plantuml server 170 | #default is http://www.plantuml.com/plantuml/svg/ 171 | svg_image_url = "https://www.plantuml.com/plantuml/svg/" 172 | 173 | # hugo module configuration 174 | 175 | [module] 176 | # Uncomment the next line to build and serve using local docsy clone declared in the named Hugo workspace: 177 | workspace = "docsy.work" 178 | [module.hugoVersion] 179 | extended = true 180 | min = "0.110.0" 181 | [[module.imports]] 182 | path = "github.com/google/docsy" 183 | disable = false 184 | -------------------------------------------------------------------------------- /layouts/404.html: -------------------------------------------------------------------------------- 1 | {{ define "main" -}} 2 |
3 |

Not found

4 |

Oops! This page doesn't exist. Try going back to the home page.

5 |

You can learn how to make a 404 page like this in Custom 404 Pages.

6 |
7 | {{- end }} 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docsy-example-site", 3 | "version": "0.8.0", 4 | "version.next": "0.8.1-dev.0-unreleased", 5 | "description": "Example site that uses Docsy theme for technical documentation.", 6 | "repository": "github:google/docsy-example", 7 | "homepage": "https://example.docsy.dev", 8 | "author": "Docsy Authors", 9 | "license": "Apache-2.0", 10 | "bugs": "https://github.com/google/docsy-example/issues", 11 | "spelling": "cSpell:ignore HTMLTEST precheck postbuild -", 12 | "scripts": { 13 | "_build": "npm run _hugo-dev --", 14 | "_check:links": "echo IMPLEMENTATION PENDING for check-links; echo", 15 | "_hugo": "hugo --cleanDestinationDir", 16 | "_hugo-dev": "npm run _hugo -- -e dev -DFE", 17 | "_local": "npx cross-env HUGO_MODULE_WORKSPACE=docsy.work", 18 | "_serve": "npm run _hugo-dev -- --minify serve", 19 | "build:preview": "npm run _hugo-dev -- --minify --baseURL \"${DEPLOY_PRIME_URL:-/}\"", 20 | "build:production": "npm run _hugo -- --minify", 21 | "build": "npm run _build -- ", 22 | "check:links:all": "HTMLTEST_ARGS= npm run _check:links", 23 | "check:links": "npm run _check:links", 24 | "clean": "rm -Rf public/* resources", 25 | "local": "npm run _local -- npm run", 26 | "make:public": "git init -b main public", 27 | "precheck:links:all": "npm run build", 28 | "precheck:links": "npm run build", 29 | "postbuild:preview": "npm run _check:links", 30 | "postbuild:production": "npm run _check:links", 31 | "serve": "npm run _serve", 32 | "test": "npm run check:links", 33 | "update:pkg:dep": "npm install --save-dev autoprefixer@latest postcss-cli@latest", 34 | "update:pkg:hugo": "npm install --save-dev --save-exact hugo-extended@latest" 35 | }, 36 | "devDependencies": { 37 | "autoprefixer": "^10.4.14", 38 | "cross-env": "^7.0.3", 39 | "hugo-extended": "0.121.1", 40 | "postcss-cli": "^11.0.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /static/favicons/android-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/android-144x144.png -------------------------------------------------------------------------------- /static/favicons/android-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/android-192x192.png -------------------------------------------------------------------------------- /static/favicons/android-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/android-36x36.png -------------------------------------------------------------------------------- /static/favicons/android-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/android-48x48.png -------------------------------------------------------------------------------- /static/favicons/android-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/android-72x72.png -------------------------------------------------------------------------------- /static/favicons/android-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/android-96x96.png -------------------------------------------------------------------------------- /static/favicons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /static/favicons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/favicon-16x16.png -------------------------------------------------------------------------------- /static/favicons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/favicon-32x32.png -------------------------------------------------------------------------------- /static/favicons/favicon-xxxx.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/favicon-xxxx.ico -------------------------------------------------------------------------------- /static/favicons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/favicon.ico -------------------------------------------------------------------------------- /static/favicons/pwa-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/pwa-192x192.png -------------------------------------------------------------------------------- /static/favicons/pwa-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/pwa-512x512.png -------------------------------------------------------------------------------- /static/favicons/tile150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/tile150x150.png -------------------------------------------------------------------------------- /static/favicons/tile310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/tile310x150.png -------------------------------------------------------------------------------- /static/favicons/tile310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/tile310x310.png -------------------------------------------------------------------------------- /static/favicons/tile70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/favicons/tile70x70.png -------------------------------------------------------------------------------- /static/google5713250934492ab9.html: -------------------------------------------------------------------------------- 1 | google-site-verification: google5713250934492ab9.html -------------------------------------------------------------------------------- /static/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/images/favicon.ico -------------------------------------------------------------------------------- /static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyao/learning-rust/08f5ea92636b5a549b0fa86dd77efe5bd072aad1/static/images/logo.png --------------------------------------------------------------------------------