├── .gitattributes ├── .gitignore ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── book.toml ├── src ├── SUMMARY.md ├── abi.md ├── appendices.md ├── attributes-redirect.html ├── attributes.md ├── attributes │ ├── codegen.md │ ├── derive.md │ ├── diagnostics.md │ ├── limits.md │ ├── testing.md │ └── type_system.md ├── behavior-considered-undefined.md ├── behavior-not-considered-unsafe.md ├── comments.md ├── conditional-compilation.md ├── const_eval.md ├── crates-and-source-files.md ├── css │ ├── reference.css │ └── summary.jpg ├── destructors.md ├── dynamically-sized-types.md ├── expressions.md ├── expressions │ ├── array-expr.md │ ├── await-expr.md │ ├── block-expr.md │ ├── call-expr.md │ ├── closure-expr.md │ ├── enum-variant-expr.md │ ├── field-expr.md │ ├── grouped-expr.md │ ├── if-expr.md │ ├── literal-expr.md │ ├── loop-expr.md │ ├── match-expr.md │ ├── method-call-expr.md │ ├── operator-expr.md │ ├── path-expr.md │ ├── range-expr.md │ ├── return-expr.md │ ├── struct-expr.md │ └── tuple-expr.md ├── glossary.md ├── identifiers.md ├── imgs │ └── contributors │ │ ├── anonymous.jpg │ │ └── zzy.jpg ├── influences.md ├── input-format.md ├── interior-mutability.md ├── introduction.md ├── items.md ├── items │ ├── associated-items.md │ ├── constant-items.md │ ├── enumerations.md │ ├── extern-crates.md │ ├── external-blocks.md │ ├── functions.md │ ├── generics.md │ ├── implementations.md │ ├── modules.md │ ├── static-items.md │ ├── structs.md │ ├── traits.md │ ├── type-aliases.md │ ├── unions.md │ └── use-declarations.md ├── keywords.md ├── lexical-structure.md ├── lifetime-elision.md ├── linkage.md ├── macro-ambiguity.md ├── macros-by-example.md ├── macros.md ├── memory-allocation-and-lifetime.md ├── memory-model.md ├── memory-ownership.md ├── notation.md ├── paths.md ├── patterns.md ├── procedural-macros.md ├── runtime.md ├── rust-glossary.md ├── special-types-and-traits.md ├── statements-and-expressions.md ├── statements.md ├── subtyping.md ├── tokens.md ├── trait-bounds.md ├── type-coercions.md ├── type-layout.md ├── type-system.md ├── types-redirect.html ├── types.md ├── types │ ├── array.md │ ├── boolean.md │ ├── closure.md │ ├── enum.md │ ├── function-item.md │ ├── function-pointer.md │ ├── impl-trait.md │ ├── inferred.md │ ├── never.md │ ├── numeric.md │ ├── parameters.md │ ├── pointer.md │ ├── slice.md │ ├── struct.md │ ├── textual.md │ ├── trait-object.md │ ├── tuple.md │ └── union.md ├── unsafe-blocks.md ├── unsafe-functions.md ├── unsafety.md ├── variables.md ├── visibility-and-privacy.md └── whitespace.md ├── stable-check ├── .gitignore ├── Cargo.lock ├── Cargo.toml └── src │ └── main.rs └── theme ├── book.js ├── css ├── chrome.css ├── general.css ├── print.css └── variables.css ├── favicon.png ├── favicon.svg ├── highlight.css ├── highlight.js └── index.hbs /.gitattributes: -------------------------------------------------------------------------------- 1 | * linguist-language=Rust 2 | 3 | *.md linguist-detectable=true 4 | docs/* linguist-documentation 5 | 6 | * text=auto eol=lf 7 | 8 | *.{cmd,[cC][mM][dD]} text eol=crlf 9 | *.{bat,[bB][aA][tT]} text eol=crlf 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Cargo.lock 3 | target/ 4 | *~ 5 | book/ 6 | *.swp 7 | lines.txt 8 | .idea/ 9 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 zzy (linshi@budshome.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rust 参考手册 2 | 3 | > 💥 暂翻译至[模块](https://rust-reference.budshome.com/items/modules.html)一节。
4 | > 欢迎您参与,我将第一时间合并 PR。谢谢! 5 | 6 | 本书是 Rust 编程语言的主要参考。 7 | 8 | 本书并非 Rust 语言规范:可能包含特定于 `rustc` 自身的细节,因此不应作为 Rust 语言规范。Rust 语言开发团队计划在未来拿出规范文件,但目前只有本书所述。 9 | 10 | > 💥 同步官方 nightly 版本。可[在线阅读 rust-reference.budshome.com](https://rust-reference.budshome.com),也可下载PDF、ePub。 11 | 12 | ## 状态 13 | 14 | - 对照源码位置:https://github.com/rust-lang/reference/tree/master/src 15 | - 每章开头有官方链接、commit hash,以及提交日期。若发现与官方不一致,欢迎 Issue 或 PR :bug: 16 | 17 | ## 依赖 18 | 19 | - rustc (Rust 编译器); 20 | - mdBook (安装命令:`cargo install mdbook`,若需要请[阅读 mdBook 中文文档](https://mdbook.budshome.com))。 21 | 22 | ## 构建 23 | 24 | 首先,克隆本仓库,并进入文件夹: 25 | 26 | ``` Bash 27 | git clone https://github.com/zzy/rust-reference-zh-cn.git 28 | cd rust-reference-zh-cn 29 | ``` 30 | 31 | 其次,测试代码,并捕获编译错误: 32 | 33 | ``` Bash 34 | mdbook test 35 | ``` 36 | 37 | 最后,生成电子书: 38 | 39 | ``` Bash 40 | mdbook build 41 | ``` 42 | 43 | 默认生成 `HTML` 文档,存放在 `docs` 文件夹中。 44 | 45 | ## 贡献者 ✨ 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 |

Zhang Zhongyu

欢迎您

欢迎您

欢迎您

欢迎您

欢迎您
57 | 58 | ## 做贡献 59 | 60 | 我们欢迎各类贡献。 61 | 62 | 欢迎 fork[《Rust 参考手册》中文翻译仓库],欢迎提交问题,欢迎发送 PR。 63 | 64 | [《Rust 参考手册》中文翻译仓库]: https://github.com/zzy/rust-reference-zh-cn 65 | -------------------------------------------------------------------------------- /book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | title = "Rust 参考手册 - The Rust Language Reference 中文版" 3 | authors = ["zzy"] 4 | language = "zh" 5 | description = "rust-reference 中文, Rust 参考手册, Rust 编程手册, Rust 编程语言, Rust 开发手册, Rust 开发指南" 6 | src = "src" 7 | multilingual = true 8 | 9 | # [build] 10 | # build-dir = "docs" 11 | 12 | [output.html] 13 | theme = "theme" 14 | # default-theme = "rust" 15 | git-repository-url = "https://github.com/zzy/rust-reference-zh-cn" 16 | curly-quotes = true 17 | mathjax-support = true 18 | 19 | [output.html.playpen] 20 | editable = true 21 | copy-js = true 22 | 23 | [output.html.search] 24 | limit-results = 20 25 | use-boolean-and = true 26 | boost-title = 2 27 | boost-hierarchy = 2 28 | boost-paragraph = 1 29 | expand = true 30 | heading-split-level = 3 31 | copy-js = true 32 | -------------------------------------------------------------------------------- /src/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Rust 参考手册 2 | 3 | 8 | 9 | [介绍](introduction.md) 10 | 11 | - [标记法](notation.md) 12 | 13 | - [词法结构](lexical-structure.md) 14 | - [输入格式](input-format.md) 15 | - [关键字](keywords.md) 16 | - [标识符](identifiers.md) 17 | - [注释](comments.md) 18 | - [空白](whitespace.md) 19 | - [记号](tokens.md) 20 | - [路径](paths.md) 21 | 22 | - [宏](macros.md) 23 | - [声明宏](macros-by-example.md) 24 | - [过程宏](procedural-macros.md) 25 | 26 | - [crate 和源文件](crates-and-source-files.md) 27 | 28 | - [条件编译](conditional-compilation.md) 29 | 30 | - [项](items.md) 31 | - [模块](items/modules.md) 32 | - [extern crate 声明](items/extern-crates.md) 33 | - [use 声明](items/use-declarations.md) 34 | - [函数](items/functions.md) 35 | - [类型别名](items/type-aliases.md) 36 | - [结构体](items/structs.md) 37 | - [枚举](items/enumerations.md) 38 | - [联合体](items/unions.md) 39 | - [常量项](items/constant-items.md) 40 | - [静态项](items/static-items.md) 41 | - [trait](items/traits.md) 42 | - [实现](items/implementations.md) 43 | - [外部块](items/external-blocks.md) 44 | - [泛型:类型和生命周期参数](items/generics.md) 45 | - [关联项](items/associated-items.md) 46 | - [可见性和私有性](visibility-and-privacy.md) 47 | 48 | - [属性](attributes.md) 49 | - [测试属性](attributes/testing.md) 50 | - [派生属性](attributes/derive.md) 51 | - [诊断属性](attributes/diagnostics.md) 52 | - [代码生成属性](attributes/codegen.md) 53 | - [limit 属性](attributes/limits.md) 54 | - [类型系统属性](attributes/type_system.md) 55 | 56 | - [语句和表达式](statements-and-expressions.md) 57 | - [语句](statements.md) 58 | - [表达式](expressions.md) 59 | - [字面量表达式](expressions/literal-expr.md) 60 | - [路径表达式](expressions/path-expr.md) 61 | - [块表达式](expressions/block-expr.md) 62 | - [运算符表达式](expressions/operator-expr.md) 63 | - [组合表达式](expressions/grouped-expr.md) 64 | - [数组和索引表达式](expressions/array-expr.md) 65 | - [元组和索引表达式](expressions/tuple-expr.md) 66 | - [结构体表达式](expressions/struct-expr.md) 67 | - [枚举变量表达式](expressions/enum-variant-expr.md) 68 | - [调用表达式](expressions/call-expr.md) 69 | - [方法调用表达式](expressions/method-call-expr.md) 70 | - [字段存取表达式](expressions/field-expr.md) 71 | - [闭包表达式](expressions/closure-expr.md) 72 | - [循环表达式](expressions/loop-expr.md) 73 | - [区间表达式](expressions/range-expr.md) 74 | - [if 和 if let 表达式](expressions/if-expr.md) 75 | - [match 表达式](expressions/match-expr.md) 76 | - [return 表达式](expressions/return-expr.md) 77 | - [await 表达式](expressions/await-expr.md) 78 | 79 | - [模式](patterns.md) 80 | 81 | - [类型系统](type-system.md) 82 | - [类型](types.md) 83 | - [布尔型](types/boolean.md) 84 | - [数值型](types/numeric.md) 85 | - [字符型](types/textual.md) 86 | - [never 型](types/never.md) 87 | - [元组](types/tuple.md) 88 | - [数组](types/array.md) 89 | - [切片](types/slice.md) 90 | - [结构体](types/struct.md) 91 | - [枚举](types/enum.md) 92 | - [union 型](types/union.md) 93 | - [函数项](types/function-item.md) 94 | - [闭包](types/closure.md) 95 | - [指针](types/pointer.md) 96 | - [函数指针](types/function-pointer.md) 97 | - [trait 对象](types/trait-object.md) 98 | - [impl trait](types/impl-trait.md) 99 | - [类型参数](types/parameters.md) 100 | - [推导型](types/inferred.md) 101 | - [DST](dynamically-sized-types.md) 102 | - [类型设计](type-layout.md) 103 | - [内部可变性](interior-mutability.md) 104 | - [子类型和变型](subtyping.md) 105 | - [trait 及其生命周期约束](trait-bounds.md) 106 | - [类型强制转换](type-coercions.md) 107 | - [析构函数](destructors.md) 108 | - [生命周期省略](lifetime-elision.md) 109 | 110 | - [特殊类型及其 trait](special-types-and-traits.md) 111 | 112 | - [内存模型](memory-model.md) 113 | - [内存分配和其生命周期](memory-allocation-and-lifetime.md) 114 | - [内存所有权](memory-ownership.md) 115 | - [变量](variables.md) 116 | 117 | - [链接](linkage.md) 118 | 119 | - [不安全性](unsafety.md) 120 | - [不安全函数](unsafe-functions.md) 121 | - [不安全块](unsafe-blocks.md) 122 | - [未定义行为](behavior-considered-undefined.md) 123 | - [不安全行为](behavior-not-considered-unsafe.md) 124 | 125 | - [常量计算](const_eval.md) 126 | 127 | - [ABI](abi.md) 128 | 129 | - [Rust 运行时](runtime.md) 130 | 131 | - [附录](appendices.md) 132 | - [宏定义规范](macro-ambiguity.md) 133 | - [受其它语言的影响](influences.md) 134 | - [术语](glossary.md) 135 | -------------------------------------------------------------------------------- /src/abi.md: -------------------------------------------------------------------------------- 1 | # Application Binary Interface (ABI) 2 | 3 | This section documents features that affect the ABI of the compiled output of 4 | a crate. 5 | 6 | See *[extern functions]* for information on specifying the ABI for exporting 7 | functions. See *[external blocks]* for information on specifying the ABI for 8 | linking external libraries. 9 | 10 | ## The `used` attribute 11 | 12 | The *`used` attribute* can only be applied to [`static` items]. This [attribute] forces the 13 | compiler to keep the variable in the output object file (.o, .rlib, etc. excluding final binaries) 14 | even if the variable is not used, or referenced, by any other item in the crate. 15 | However, the linker is still free to remove such an item. 16 | 17 | Below is an example that shows under what conditions the compiler keeps a `static` item in the 18 | output object file. 19 | 20 | ``` rust 21 | // foo.rs 22 | 23 | // This is kept because of `#[used]`: 24 | #[used] 25 | static FOO: u32 = 0; 26 | 27 | // This is removable because it is unused: 28 | #[allow(dead_code)] 29 | static BAR: u32 = 0; 30 | 31 | // This is kept because it is publicly reachable: 32 | pub static BAZ: u32 = 0; 33 | 34 | // This is kept because it is referenced by a public, reachable function: 35 | static QUUX: u32 = 0; 36 | 37 | pub fn quux() -> &'static u32 { 38 | &QUUX 39 | } 40 | 41 | // This is removable because it is referenced by a private, unused (dead) function: 42 | static CORGE: u32 = 0; 43 | 44 | #[allow(dead_code)] 45 | fn corge() -> &'static u32 { 46 | &CORGE 47 | } 48 | ``` 49 | 50 | ``` console 51 | $ rustc -O --emit=obj --crate-type=rlib foo.rs 52 | 53 | $ nm -C foo.o 54 | 0000000000000000 R foo::BAZ 55 | 0000000000000000 r foo::FOO 56 | 0000000000000000 R foo::QUUX 57 | 0000000000000000 T foo::quux 58 | ``` 59 | 60 | ## The `no_mangle` attribute 61 | 62 | The *`no_mangle` attribute* may be used on any [item] to disable standard 63 | symbol name mangling. The symbol for the item will be the identifier of the 64 | item's name. 65 | 66 | ## The `link_section` attribute 67 | 68 | The *`link_section` attribute* specifies the section of the object file that a 69 | [function] or [static]'s content will be placed into. It uses the 70 | [_MetaNameValueStr_] syntax to specify the section name. 71 | 72 | 73 | ```rust,no_run 74 | #[no_mangle] 75 | #[link_section = ".example_section"] 76 | pub static VAR1: u32 = 1; 77 | ``` 78 | 79 | ## The `export_name` attribute 80 | 81 | The *`export_name` attribute* specifies the name of the symbol that will be 82 | exported on a [function] or [static]. It uses the [_MetaNameValueStr_] syntax 83 | to specify the symbol name. 84 | 85 | ```rust 86 | #[export_name = "exported_symbol_name"] 87 | pub fn name_in_rust() { } 88 | ``` 89 | 90 | [_MetaNameValueStr_]: attributes.md#meta-item-attribute-syntax 91 | [`static` items]: items/static-items.md 92 | [attribute]: attributes.md 93 | [extern functions]: items/functions.md#extern-function-qualifier 94 | [external blocks]: items/external-blocks.md 95 | [function]: items/functions.md 96 | [item]: items.md 97 | [static]: items/static-items.md 98 | -------------------------------------------------------------------------------- /src/appendices.md: -------------------------------------------------------------------------------- 1 | # Appendices 2 | -------------------------------------------------------------------------------- /src/attributes-redirect.html: -------------------------------------------------------------------------------- 1 | 30 | -------------------------------------------------------------------------------- /src/attributes/derive.md: -------------------------------------------------------------------------------- 1 | # Derive 2 | 3 | The *`derive` attribute* allows new [items] to be automatically generated for 4 | data structures. It uses the [_MetaListPaths_] syntax to specify a list of 5 | traits to implement or paths to [derive macros] to process. 6 | 7 | For example, the following will create an [`impl` item] for the 8 | [`PartialEq`] and [`Clone`] traits for `Foo`, and the type parameter `T` will be 9 | given the `PartialEq` or `Clone` constraints for the appropriate `impl`: 10 | 11 | ```rust 12 | #[derive(PartialEq, Clone)] 13 | struct Foo { 14 | a: i32, 15 | b: T, 16 | } 17 | ``` 18 | 19 | The generated `impl` for `PartialEq` is equivalent to 20 | 21 | ```rust 22 | # struct Foo { a: i32, b: T } 23 | impl PartialEq for Foo { 24 | fn eq(&self, other: &Foo) -> bool { 25 | self.a == other.a && self.b == other.b 26 | } 27 | 28 | fn ne(&self, other: &Foo) -> bool { 29 | self.a != other.a || self.b != other.b 30 | } 31 | } 32 | ``` 33 | 34 | You can implement `derive` for your own traits through [procedural macros]. 35 | 36 | [_MetaListPaths_]: ../attributes.md#meta-item-attribute-syntax 37 | [`Clone`]: ../../std/clone/trait.Clone.html 38 | [`PartialEq`]: ../../std/cmp/trait.PartialEq.html 39 | [`impl` item]: ../items/implementations.md 40 | [items]: ../items.md 41 | [derive macros]: ../procedural-macros.md#derive-macros 42 | [procedural macros]: ../procedural-macros.md#derive-macros 43 | -------------------------------------------------------------------------------- /src/attributes/limits.md: -------------------------------------------------------------------------------- 1 | # Limits 2 | 3 | The following [attributes] affect compile-time limits. 4 | 5 | ## The `recursion_limit` attribute 6 | 7 | The *`recursion_limit` attribute* may be applied at the [crate] level to set the 8 | maximum depth for potentially infinitely-recursive compile-time operations 9 | like macro expansion or auto-dereference. It uses the [_MetaNameValueStr_] 10 | syntax to specify the recursion depth. 11 | 12 | > Note: The default in `rustc` is 128. 13 | 14 | ```rust,compile_fail 15 | #![recursion_limit = "4"] 16 | 17 | macro_rules! a { 18 | () => { a!(1) }; 19 | (1) => { a!(2) }; 20 | (2) => { a!(3) }; 21 | (3) => { a!(4) }; 22 | (4) => { }; 23 | } 24 | 25 | // This fails to expand because it requires a recursion depth greater than 4. 26 | a!{} 27 | ``` 28 | 29 | ```rust,compile_fail 30 | #![recursion_limit = "1"] 31 | 32 | // This fails because it requires two recursive steps to auto-derefence. 33 | (|_: &u8| {})(&&1); 34 | ``` 35 | 36 | ## The `type_length_limit` attribute 37 | 38 | The *`type_length_limit` attribute* limits the maximum number of type 39 | substitutions made when constructing a concrete type during monomorphization. 40 | It is applied at the [crate] level, and uses the [_MetaNameValueStr_] syntax 41 | to set the limit based on the number of type substitutions. 42 | 43 | > Note: The default in `rustc` is 1048576. 44 | 45 | 48 | 49 | ```rust,compile_fail,ignore 50 | #![type_length_limit = "8"] 51 | 52 | fn f(x: T) {} 53 | 54 | // This fails to compile because monomorphizing to 55 | // `f::<(i32, i32, i32, i32, i32, i32, i32, i32, i32)>>` requires more 56 | // than 8 type elements. 57 | f((1, 2, 3, 4, 5, 6, 7, 8, 9)); 58 | ``` 59 | 60 | [_MetaNameValueStr_]: ../attributes.md#meta-item-attribute-syntax 61 | [attributes]: ../attributes.md 62 | [crate]: ../crates-and-source-files.md 63 | -------------------------------------------------------------------------------- /src/attributes/testing.md: -------------------------------------------------------------------------------- 1 | # Testing attributes 2 | 3 | The following [attributes] are used for specifying functions for performing 4 | tests. Compiling a crate in "test" mode enables building the test functions 5 | along with a test harness for executing the tests. Enabling the test mode also 6 | enables the [`test` conditional compilation option]. 7 | 8 | ## The `test` attribute 9 | 10 | The *`test` attribute* marks a function to be executed as a test. These 11 | functions are only compiled when in test mode. Test functions must be free, 12 | monomorphic functions that take no arguments, and the return type must be one 13 | of the following: 14 | 15 | * `()` 16 | * `Result<(), E> where E: Error` 17 | 18 | 19 | 20 | > Note: The implementation of which return types are allowed is determined by 21 | > the unstable [`Termination`] trait. 22 | 23 | 25 | 26 | > Note: The test mode is enabled by passing the `--test` argument to `rustc` 27 | > or using `cargo test`. 28 | 29 | Tests that return `()` pass as long as they terminate and do not panic. Tests 30 | that return a `Result<(), E>` pass as long as they return `Ok(())`. Tests that 31 | do not terminate neither pass nor fail. 32 | 33 | ```rust 34 | # use std::io; 35 | # fn setup_the_thing() -> io::Result { Ok(1) } 36 | # fn do_the_thing(s: &i32) -> io::Result<()> { Ok(()) } 37 | #[test] 38 | fn test_the_thing() -> io::Result<()> { 39 | let state = setup_the_thing()?; // expected to succeed 40 | do_the_thing(&state)?; // expected to succeed 41 | Ok(()) 42 | } 43 | ``` 44 | 45 | ## The `ignore` attribute 46 | 47 | A function annotated with the `test` attribute can also be annotated with the 48 | `ignore` attribute. The *`ignore` attribute* tells the test harness to not 49 | execute that function as a test. It will still be compiled when in test mode. 50 | 51 | The `ignore` attribute may optionally be written with the [_MetaNameValueStr_] 52 | syntax to specify a reason why the test is ignored. 53 | 54 | ```rust 55 | #[test] 56 | #[ignore = "not yet implemented"] 57 | fn mytest() { 58 | // … 59 | } 60 | ``` 61 | 62 | > **Note**: The `rustc` test harness supports the `--include-ignored` flag to 63 | > force ignored tests to be run. 64 | 65 | ## The `should_panic` attribute 66 | 67 | A function annotated with the `test` attribute that returns `()` can also be 68 | annotated with the `should_panic` attribute. The *`should_panic` attribute* 69 | makes the test only pass if it actually panics. 70 | 71 | The `should_panic` attribute may optionally take an input string that must 72 | appear within the panic message. If the string is not found in the message, 73 | then the test will fail. The string may be passed using the 74 | [_MetaNameValueStr_] syntax or the [_MetaListNameValueStr_] syntax with an 75 | `expected` field. 76 | 77 | ```rust 78 | #[test] 79 | #[should_panic(expected = "values don't match")] 80 | fn mytest() { 81 | assert_eq!(1, 2, "values don't match"); 82 | } 83 | ``` 84 | 85 | [_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax 86 | [_MetaNameValueStr_]: ../attributes.md#meta-item-attribute-syntax 87 | [`Termination`]: ../../std/process/trait.Termination.html 88 | [`test` conditional compilation option]: ../conditional-compilation.md#test 89 | [attributes]: ../attributes.md 90 | -------------------------------------------------------------------------------- /src/attributes/type_system.md: -------------------------------------------------------------------------------- 1 | # Type system attributes 2 | 3 | The following [attributes] are used for changing how a type can be used. 4 | 5 | ## The `non_exhaustive` attribute 6 | 7 | The *`non_exhaustive` attribute* indicates that a type or variant may have 8 | more fields or variants added in the future. It can be applied to 9 | [`struct`s][struct], [`enum`s][enum], and `enum` variants. 10 | 11 | The `non_exhaustive` attribute uses the [_MetaWord_] syntax and thus does not 12 | take any inputs. 13 | 14 | Within the defining crate, `non_exhaustive` has no effect. 15 | 16 | ```rust 17 | #[non_exhaustive] 18 | pub struct Config { 19 | pub window_width: u16, 20 | pub window_height: u16, 21 | } 22 | 23 | #[non_exhaustive] 24 | pub enum Error { 25 | Message(String), 26 | Other, 27 | } 28 | 29 | pub enum Message { 30 | #[non_exhaustive] Send { from: u32, to: u32, contents: String }, 31 | #[non_exhaustive] Reaction(u32), 32 | #[non_exhaustive] Quit, 33 | } 34 | 35 | // Non-exhaustive structs can be constructed as normal within the defining crate. 36 | let config = Config { window_width: 640, window_height: 480 }; 37 | 38 | // Non-exhaustive structs can be matched on exhaustively within the defining crate. 39 | if let Config { window_width, window_height } = config { 40 | // ... 41 | } 42 | 43 | let error = Error::Other; 44 | let message = Message::Reaction(3); 45 | 46 | // Non-exhaustive enums can be matched on exhaustively within the defining crate. 47 | match error { 48 | Error::Message(ref s) => { }, 49 | Error::Other => { }, 50 | } 51 | 52 | match message { 53 | // Non-exhaustive variants can be matched on exhaustively within the defining crate. 54 | Message::Send { from, to, contents } => { }, 55 | Message::Reaction(id) => { }, 56 | Message::Quit => { }, 57 | } 58 | ``` 59 | 60 | Outside of the defining crate, types annotated with `non_exhaustive` have limitations that 61 | preserve backwards compatibility when new fields or variants are added. 62 | 63 | Non-exhaustive types cannot be constructed outside of the defining crate: 64 | 65 | - Non-exhaustive variants ([`struct`][struct] or [`enum` variant][enum]) cannot be constructed 66 | with a [_StructExpression_] \(including with [functional update syntax]). 67 | - [`enum`][enum] instances can be constructed in an [_EnumerationVariantExpression_]. 68 | 69 | 70 | ```rust,ignore 71 | // `Config`, `Error`, and `Message` are types defined in an upstream crate that have been 72 | // annotated as `#[non_exhaustive]`. 73 | use upstream::{Config, Error, Message}; 74 | 75 | // Cannot construct an instance of `Config`, if new fields were added in 76 | // a new version of `upstream` then this would fail to compile, so it is 77 | // disallowed. 78 | let config = Config { window_width: 640, window_height: 480 }; 79 | 80 | // Can construct an instance of `Error`, new variants being introduced would 81 | // not result in this failing to compile. 82 | let error = Error::Message("foo".to_string()); 83 | 84 | // Cannot construct an instance of `Message::Send` or `Message::Reaction`, 85 | // if new fields were added in a new version of `upstream` then this would 86 | // fail to compile, so it is disallowed. 87 | let message = Message::Send { from: 0, to: 1, contents: "foo".to_string(), }; 88 | let message = Message::Reaction(0); 89 | 90 | // Cannot construct an instance of `Message::Quit`, if this were converted to 91 | // a tuple-variant `upstream` then this would fail to compile. 92 | let message = Message::Quit; 93 | ``` 94 | 95 | There are limitations when matching on non-exhaustive types outside of the defining crate: 96 | 97 | - When pattern matching on a non-exhaustive variant ([`struct`][struct] or [`enum` variant][enum]), 98 | a [_StructPattern_] must be used which must include a `..`. Tuple variant constructor visibility 99 | is lowered to `min($vis, pub(crate))`. 100 | - When pattern matching on a non-exhaustive [`enum`][enum], matching on a variant does not 101 | contribute towards the exhaustiveness of the arms. 102 | 103 | 104 | ```rust, ignore 105 | // `Config`, `Error`, and `Message` are types defined in an upstream crate that have been 106 | // annotated as `#[non_exhaustive]`. 107 | use upstream::{Config, Error, Message}; 108 | 109 | // Cannot match on a non-exhaustive enum without including a wildcard arm. 110 | match error { 111 | Error::Message(ref s) => { }, 112 | Error::Other => { }, 113 | // would compile with: `_ => {},` 114 | } 115 | 116 | // Cannot match on a non-exhaustive struct without a wildcard. 117 | if let Ok(Config { window_width, window_height }) = config { 118 | // would compile with: `..` 119 | } 120 | 121 | match message { 122 | // Cannot match on a non-exhaustive struct enum variant without including a wildcard. 123 | Message::Send { from, to, contents } => { }, 124 | // Cannot match on a non-exhaustive tuple or unit enum variant. 125 | Message::Reaction(type) => { }, 126 | Message::Quit => { }, 127 | } 128 | ``` 129 | 130 | Non-exhaustive types are always considered inhabited in downstream crates. 131 | 132 | [_EnumerationVariantExpression_]: ../expressions/enum-variant-expr.md 133 | [_MetaWord_]: ../attributes.md#meta-item-attribute-syntax 134 | [_StructExpression_]: ../expressions/struct-expr.md 135 | [_StructPattern_]: ../patterns.md#struct-patterns 136 | [_TupleStructPattern_]: ../patterns.md#tuple-struct-patterns 137 | [`if let`]: ../expressions/if-expr.md#if-let-expressions 138 | [`match`]: ../expressions/match-expr.md 139 | [attributes]: ../attributes.md 140 | [enum]: ../items/enumerations.md 141 | [functional update syntax]: ../expressions/struct-expr.md#functional-update-syntax 142 | [struct]: ../items/structs.md 143 | -------------------------------------------------------------------------------- /src/behavior-considered-undefined.md: -------------------------------------------------------------------------------- 1 | ## Behavior considered undefined 2 | 3 | Rust code is incorrect if it exhibits any of the behaviors in the following 4 | list. This includes code within `unsafe` blocks and `unsafe` functions. 5 | `unsafe` only means that avoiding undefined behavior is on the programmer; it 6 | does not change anything about the fact that Rust programs must never cause 7 | undefined behavior. 8 | 9 | It is the programmer's responsibility when writing `unsafe` code to ensure that 10 | any safe code interacting with the `unsafe` code cannot trigger these 11 | behaviors. `unsafe` code that satisfies this property for any safe client is 12 | called *sound*; if `unsafe` code can be misused by safe code to exhibit 13 | undefined behavior, it is *unsound*. 14 | 15 |
16 | 17 | ***Warning:*** The following list is not exhaustive. There is no formal model of 18 | Rust's semantics for what is and is not allowed in unsafe code, so there may be 19 | more behavior considered unsafe. The following list is just what we know for 20 | sure is undefined behavior. Please read the [Rustonomicon] before writing unsafe 21 | code. 22 | 23 |
24 | 25 | * Data races. 26 | * Dereferencing (using the `*` operator on) a dangling or unaligned raw pointer. 27 | * Breaking the [pointer aliasing rules]. `&mut T` and `&T` follow LLVM’s scoped 28 | [noalias] model, except if the `&T` contains an [`UnsafeCell`]. 29 | * Mutating immutable data. All data inside a [`const`] item is immutable. Moreover, all 30 | data reached through a shared reference or data owned by an immutable binding 31 | is immutable, unless that data is contained within an [`UnsafeCell`]. 32 | * Invoking undefined behavior via compiler intrinsics. 33 | * Executing code compiled with platform features that the current platform 34 | does not support (see [`target_feature`]). 35 | * Calling a function with the wrong call ABI or unwinding from a function with the wrong unwind ABI. 36 | * Producing an invalid value, even in private fields and locals. "Producing" a 37 | value happens any time a value is assigned to or read from a place, passed to 38 | a function/primitive operation or returned from a function/primitive 39 | operation. 40 | The following values are invalid (at their respective type): 41 | * A value other than `false` (`0`) or `true` (`1`) in a `bool`. 42 | * A discriminant in an `enum` not included in the type definition. 43 | * A null `fn` pointer. 44 | * A value in a `char` which is a surrogate or above `char::MAX`. 45 | * A `!` (all values are invalid for this type). 46 | * An integer (`i*`/`u*`), floating point value (`f*`), or raw pointer obtained 47 | from [uninitialized memory][undef]. 48 | * A reference or `Box` that is dangling, unaligned, or points to an invalid value. 49 | * Invalid metadata in a wide reference, `Box`, or raw pointer: 50 | * `dyn Trait` metadata is invalid if it is not a pointer to a vtable for 51 | `Trait` that matches the actual dynamic trait the pointer or reference points to. 52 | * Slice metadata is invalid if the length is not a valid `usize` 53 | (i.e., it must not be read from uninitialized memory). 54 | * Non-UTF-8 byte sequences in a `str`. 55 | * Invalid values for a type with a custom definition of invalid values. 56 | In the standard library, this affects [`NonNull`] and [`NonZero*`]. 57 | 58 | > **Note**: `rustc` achieves this with the unstable 59 | > `rustc_layout_scalar_valid_range_*` attributes. 60 | 61 | A reference/pointer is "dangling" if it is null or not all of the bytes it 62 | points to are part of the same allocation (so in particular they all have to be 63 | part of *some* allocation). The span of bytes it points to is determined by the 64 | pointer value and the size of the pointee type. As a consequence, if the span is 65 | empty, "dangling" is the same as "non-null". Note that slices point to their 66 | entire range, so it is important that the length metadata is never too 67 | large. In particular, allocations and therefore slices cannot be bigger than 68 | `isize::MAX` bytes. 69 | 70 | > **Note**: Undefined behavior affects the entire program. For example, calling 71 | > a function in C that exhibits undefined behavior of C means your entire 72 | > program contains undefined behaviour that can also affect the Rust code. And 73 | > vice versa, undefined behavior in Rust can cause adverse affects on code 74 | > executed by any FFI calls to other languages. 75 | 76 | [`const`]: items/constant-items.html 77 | [noalias]: http://llvm.org/docs/LangRef.html#noalias 78 | [pointer aliasing rules]: http://llvm.org/docs/LangRef.html#pointer-aliasing-rules 79 | [undef]: http://llvm.org/docs/LangRef.html#undefined-values 80 | [`target_feature`]: attributes/codegen.md#the-target_feature-attribute 81 | [`UnsafeCell`]: ../std/cell/struct.UnsafeCell.html 82 | [Rustonomicon]: ../nomicon/index.html 83 | [`NonNull`]: ../core/ptr/struct.NonNull.html 84 | [`NonZero*`]: ../core/num/index.html 85 | -------------------------------------------------------------------------------- /src/behavior-not-considered-unsafe.md: -------------------------------------------------------------------------------- 1 | ## Behavior not considered `unsafe` 2 | 3 | The Rust compiler does not consider the following behaviors _unsafe_, 4 | though a programmer may (should) find them undesirable, unexpected, 5 | or erroneous. 6 | 7 | ##### Deadlocks 8 | ##### Leaks of memory and other resources 9 | ##### Exiting without calling destructors 10 | ##### Exposing randomized base addresses through pointer leaks 11 | ##### Integer overflow 12 | 13 | If a program contains arithmetic overflow, the programmer has made an 14 | error. In the following discussion, we maintain a distinction between 15 | arithmetic overflow and wrapping arithmetic. The first is erroneous, 16 | while the second is intentional. 17 | 18 | When the programmer has enabled `debug_assert!` assertions (for 19 | example, by enabling a non-optimized build), implementations must 20 | insert dynamic checks that `panic` on overflow. Other kinds of builds 21 | may result in `panics` or silently wrapped values on overflow, at the 22 | implementation's discretion. 23 | 24 | In the case of implicitly-wrapped overflow, implementations must 25 | provide well-defined (even if still considered erroneous) results by 26 | using two's complement overflow conventions. 27 | 28 | The integral types provide inherent methods to allow programmers 29 | explicitly to perform wrapping arithmetic. For example, 30 | `i32::wrapping_add` provides two's complement, wrapping addition. 31 | 32 | The standard library also provides a `Wrapping` newtype which 33 | ensures all standard arithmetic operations for `T` have wrapping 34 | semantics. 35 | 36 | See [RFC 560] for error conditions, rationale, and more details about 37 | integer overflow. 38 | 39 | [RFC 560]: https://github.com/rust-lang/rfcs/blob/master/text/0560-integer-overflow.md 40 | -------------------------------------------------------------------------------- /src/comments.md: -------------------------------------------------------------------------------- 1 | # 注释 2 | 3 | > [comments.md](https://github.com/rust-lang/reference/blob/master/src/comments.md) 4 | >
5 | > commit 993393d362cae51584d580f86c4f38d43ae76efc 6 | 7 | > **Lexer**\ 8 | > 行注释:\ 9 | >       `//` (~[`/` `!`] | `//`) ~`\n`\*\ 10 | >    | `//` 11 | > 12 | > 块注释:\ 13 | >       `/*` (~[`*` `!`] | `**` | _BlockCommentOrDoc_) 14 | > (_BlockCommentOrDoc_ | ~`*/`)\* `*/`\ 15 | >    | `/**/`\ 16 | >    | `/***/` 17 | > 18 | > 内部行文档注释: 19 | > > *译者注*:此风格文档注释包含注释的项,而不是为注释之后的项增加文档。这通常用于 crate 根文件(通常是 src/lib.rs)或模块的根文件为 crate 或模块整体提供文档。 20 | > 21 | >    `//!` ~[`\n` _IsolatedCR_]\* 22 | > 23 | > 内部块文档注释: 24 | > > *译者注*:此风格文档注释包含注释的项,而不是为注释之后的项增加文档。这通常用于 crate 根文件(通常是 src/lib.rs)或模块的根文件为 crate 或模块整体提供文档。 25 | > 26 | >    `/*!` ( _BlockCommentOrDoc_ | ~[`*/` _IsolatedCR_] )\* `*/` 27 | > 28 | > 外部行文档注释: 29 | > > *译者注*:此风格文档注释位于需要文档的项之前,为注释之后的项增加文档。 30 | > 31 | >    `///` (~`/` ~[`\n` _IsolatedCR_]\*)? 32 | > 33 | > 外部块文档注释: 34 | > > *译者注*:此风格文档注释位于需要文档的项之前,为注释之后的项增加文档。 35 | > 36 | >    `/**` (~`*` | _BlockCommentOrDoc_ ) 37 | > (_BlockCommentOrDoc_ | ~[`*/` _IsolatedCR_])\* `*/` 38 | > 39 | > _BlockCommentOrDoc_ :\ 40 | >       BLOCK_COMMENT\ 41 | >    | OUTER_BLOCK_DOC\ 42 | >    | INNER_BLOCK_DOC 43 | > 44 | > _IsolatedCR_ :\ 45 | >    _A `\r` not followed by a `\n`_ 46 | 47 | ## 非文档注释 48 | 49 | Rust 代码中的注释大体上遵循 C++ 风格的行(`//`)和块(`/* ... */`)注释形式,嵌套块注释也被支持。 50 | 51 | 非文档注释被当作空白的形式解析。 52 | 53 | ## 文档注释 54 | 55 | 以 *三个斜线(`///`)* 开始的行文档注释,以及以 *一个斜线和两个星号(`/** ... */`)* 开始的块文档注释,均为内部文档注释。它们被作为 [`doc` 属性]的一个特殊语法解析。也就是说,它们等同于在注释体周围写上 `#[doc="..."]`。例如:`/// Foo` 等同于 56 | `#[doc="Foo"]`,`/** Bar */` 等同于 `#[doc="Bar"]`。 57 | 58 | 以 `//!` 开始的行注释,以及以 `/*! ... */` 开始的块注释,是应用于注释体的父对象的文档注释,而非注释体之后的项。也就是说,它们等同于在注释体周围写上 `#![doc="..."]`。`//!` 注释通常用于说明源文件中的模块。 59 | 60 | 孤立的 CRs(`\r`)——譬如其后无 LF(`\n`),在文档注释中是不被允许的。 61 | 62 | ## 示例 63 | 64 | ```rust 65 | //! A doc comment that applies to the implicit anonymous module of this crate 66 | 67 | pub mod outer_module { 68 | 69 | //! - Inner line doc 70 | //!! - Still an inner line doc (but with a bang at the beginning) 71 | 72 | /*! - Inner block doc */ 73 | /*!! - Still an inner block doc (but with a bang at the beginning) */ 74 | 75 | // - Only a comment 76 | /// - Outer line doc (exactly 3 slashes) 77 | //// - Only a comment 78 | 79 | /* - Only a comment */ 80 | /** - Outer block doc (exactly) 2 asterisks */ 81 | /*** - Only a comment */ 82 | 83 | pub mod inner_module {} 84 | 85 | pub mod nested_comments { 86 | /* In Rust /* we can /* nest comments */ */ */ 87 | 88 | // All three types of block comments can contain or be nested inside 89 | // any other type: 90 | 91 | /* /* */ /** */ /*! */ */ 92 | /*! /* */ /** */ /*! */ */ 93 | /** /* */ /** */ /*! */ */ 94 | pub mod dummy_item {} 95 | } 96 | 97 | pub mod degenerate_cases { 98 | // empty inner line doc 99 | //! 100 | 101 | // empty inner block doc 102 | /*!*/ 103 | 104 | // empty line comment 105 | // 106 | 107 | // empty outer line doc 108 | /// 109 | 110 | // empty block comment 111 | /**/ 112 | 113 | pub mod dummy_item {} 114 | 115 | // empty 2-asterisk block isn't a doc block, it is a block comment 116 | /***/ 117 | 118 | } 119 | 120 | /* The next one isn't allowed because outer doc comments 121 | require an item that will receive the doc */ 122 | 123 | /// Where is my item? 124 | # mod boo {} 125 | } 126 | ``` 127 | 128 | [`doc` 属性]: attributes.md 129 | -------------------------------------------------------------------------------- /src/const_eval.md: -------------------------------------------------------------------------------- 1 | # Constant evaluation 2 | 3 | Constant evaluation is the process of computing the result of 4 | [expressions] during compilation. Only a subset of all expressions 5 | can be evaluated at compile-time. 6 | 7 | ## Constant expressions 8 | 9 | Certain forms of expressions, called constant expressions, can be evaluated at 10 | compile time. In [const contexts](#const-context), these are the only allowed 11 | expressions, and are always evaluated at compile time. In other places, such as 12 | [let statements], constant expressions *may* 13 | be, but are not guaranteed to be, evaluated at compile time. Behaviors such as 14 | out of bounds [array indexing] or [overflow] are compiler errors if the value 15 | must be evaluated at compile time (i.e. in const contexts). Otherwise, these 16 | behaviors are warnings, but will likely panic at run-time. 17 | 18 | The following expressions are constant expressions, so long as any operands are 19 | also constant expressions and do not cause any [`Drop::drop`][destructors] calls 20 | to be run. 21 | 22 | * [Literals]. 23 | * [Paths] to [functions] and constants. 24 | Recursively defining constants is not allowed. 25 | * [Tuple expressions]. 26 | * [Array expressions]. 27 | * [Struct] expressions. 28 | * [Enum variant] expressions. 29 | * [Block expressions], including `unsafe` blocks. 30 | * [let statements] and thus irrefutable [patterns], with the caveat that until `if` and `match` 31 | are implemented, one cannot use both short circuiting operators (`&&` and `||`) and let 32 | statements within the same constant. 33 | * [assignment expressions] 34 | * [compound assignment expressions] 35 | * [expression statements] 36 | * [Field] expressions. 37 | * Index expressions, [array indexing] or [slice] with a `usize`. 38 | * [Range expressions]. 39 | * [Closure expressions] which don't capture variables from the environment. 40 | * Built-in [negation], [arithmetic], [logical], [comparison] or [lazy boolean] 41 | operators used on integer and floating point types, `bool`, and `char`. 42 | * Shared [borrow]s, except if applied to a type with [interior mutability]. 43 | * The [dereference operator]. 44 | * [Grouped] expressions. 45 | * [Cast] expressions, except pointer to address and 46 | function pointer to address casts. 47 | * Calls of [const functions] and const methods. 48 | 49 | ## Const context 50 | 51 | A _const context_ is one of the following: 52 | 53 | * [Array type length expressions] 54 | * Repeat expression length expressions 55 | * The initializer of 56 | * [constants] 57 | * [statics] 58 | * [enum discriminants] 59 | 60 | [arithmetic]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators 61 | [array expressions]: expressions/array-expr.md 62 | [array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions 63 | [array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions 64 | [array type length expressions]: types/array.md 65 | [assignment expressions]: expressions/operator-expr.md#assignment-expressions 66 | [compound assignment expressions]: expressions/operator-expr.md#compound-assignment-expressions 67 | [block expressions]: expressions/block-expr.md 68 | [borrow]: expressions/operator-expr.md#borrow-operators 69 | [cast]: expressions/operator-expr.md#type-cast-expressions 70 | [closure expressions]: expressions/closure-expr.md 71 | [comparison]: expressions/operator-expr.md#comparison-operators 72 | [const functions]: items/functions.md#const-functions 73 | [constants]: items/constant-items.md 74 | [dereference operator]: expressions/operator-expr.md#the-dereference-operator 75 | [destructors]: destructors.md 76 | [enum discriminants]: items/enumerations.md#custom-discriminant-values-for-fieldless-enumerations 77 | [enum variant]: expressions/enum-variant-expr.md 78 | [expression statements]: statements.md#expression-statements 79 | [expressions]: expressions.md 80 | [field]: expressions/field-expr.md 81 | [functions]: items/functions.md 82 | [grouped]: expressions/grouped-expr.md 83 | [interior mutability]: interior-mutability.md 84 | [lazy boolean]: expressions/operator-expr.md#lazy-boolean-operators 85 | [let statements]: statements.md#let-statements 86 | [literals]: expressions/literal-expr.md 87 | [logical]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators 88 | [negation]: expressions/operator-expr.md#negation-operators 89 | [overflow]: expressions/operator-expr.md#overflow 90 | [paths]: expressions/path-expr.md 91 | [patterns]: patterns.md 92 | [range expressions]: expressions/range-expr.md 93 | [slice]: types/slice.md 94 | [statics]: items/static-items.md 95 | [struct]: expressions/struct-expr.md 96 | [tuple expressions]: expressions/tuple-expr.md 97 | -------------------------------------------------------------------------------- /src/crates-and-source-files.md: -------------------------------------------------------------------------------- 1 | # crate 和源文件 2 | 3 | > [crates-and-source-files.md](https://github.com/rust-lang/reference/blob/master/src/crates-and-source-files.md) 4 | >
5 | > commit - 277587a55aa24d8f6a66ddb43493e150c916ef43 - 2020-07-02 6 | 7 | > **Syntax**\ 8 | > _Crate_ :\ 9 | >    UTF8BOM?\ 10 | >    SHEBANG?\ 11 | >    [_InnerAttribute_]\*\ 12 | >    [_Item_]\* 13 | 14 | > **Lexer**\ 15 | > UTF8BOM : `\uFEFF`\ 16 | > SHEBANG : `#!` ~[`[` `\n`] ~`\n`\* 17 | 18 | > 注:尽管 Rust 和其他语言一样,可以由解释器和编译器来实现,但现有的唯一实现是编译器,而且 Rust 语言一直都是为编译而设计的。基于这些原因,本章节设定为编译器。 19 | 20 | Rust 语言语义遵循编译时和运行时之间的 *阶段区别*。[^phase-distinction] 具有 *静态解释* 的语义规则,以控制编译的成功或失败;而具有 *动态解释* 的语义规则,将控制程序的运行时行为。 21 | 22 | 编译模型以 _crates_ 的构件为中心。每次编译都会以源代码的形式处理一个单独的 crate。如果编译成功,将生成二进制形式的单个 23 | crate:一个可执行文件或某种类型的库。[^cratesourcefile] 24 | 25 | _crate_ 是编译和链接的单元,也是版本控制、发布和运行时加载的单元。crate 包含嵌套[模块][module]作用域的*树*。该树的顶层是一个匿名的模块(从模块内路径的角度来看),crate 中的任何项都有一个规范的[模块路径][module path],表示其在 crate 的模块树中的位置。 26 | 27 | Rust 编译器总是使用单个源文件作为输入来调用,并且总是生成一个输出 crate。对该源文件的处理可能导致其他源文件作为模块加载。源文件的扩展名为 `.rs`。 28 | 29 | Rust 源文件描述了一个模块,其名称和位置——在当前 crate 的模块树中——是从源文件外部定义的:要么通过引用源文件中的显式[模块][module]项,要么通过 crate 本身的名称。每个源文件都是一个模块,但并非每个模块都需要自己的源文件:[模块定义][module]可以嵌套在一个文件中。 30 | 31 | 每个源文件都包含一个序列——由零个或多个[项][_Item_]定义,序列可应用于源文件所包含的模块,并且可选地从任意数量的[属性][attributes]开始,这些属性中的大多数都会影响编译器的行为。crate 作为一个整体,匿名 crate 模块可以具有应用于整个 crate 的附加属性。 32 | 33 | ```rust 34 | // Specify the crate name. 35 | #![crate_name = "projx"] 36 | 37 | // Specify the type of output artifact. 38 | #![crate_type = "lib"] 39 | 40 | // Turn on a warning. 41 | // This can be done in any module, not just the anonymous crate module. 42 | #![warn(non_camel_case_types)] 43 | ``` 44 | 45 | ## 字节序标记 46 | 47 | 可选的 [UTF8 字节序标记][_UTF8 byte order mark_](由 UTF8BOM 生成)表示文件是 UTF8 编码。它只能出现在文件的开头,编译器会忽略它。 48 | 49 | ## 释伴(Shebang) 50 | 51 | 源文件可以有一个[释伴][_shebang_](由 SHEBANG 生成),它指示操作系统使用什么程序来执行此文件。它本质上是将源文件作为可执行脚本处理。释伴只能出现在文件的开头(但是在可选的 _UTF8BOM_ 之后)。它被编译器忽略。例如: 52 | 53 | 54 | ```rust,ignore 55 | #!/usr/bin/env rustx 56 | 57 | fn main() { 58 | println!("Hello!"); 59 | } 60 | ``` 61 | 62 | Rust 中对释伴语法进行了限制,以避免与[属性][attribute]混淆。`#!` 字符后面不能跟随 `[` 记号,忽略中间的[注释][comments]或[空格][whitespace]。如果此限制失败,则它不被视为释伴,而是作为属性的开始。 63 | 64 | ## Preludes 和 `no_std` 65 | 66 | 所有 crates 都有一个 *prelude*,它自动将特定模块——*prelude 模块*——的名称插入到每个[模块][module]的作用域,并将 [`extern 67 | crate`] 插入到 crate 根模块。默认情况下,使用 *标准 prelude*,链接的 crate 是 [`std`],prelude 模块是 [`std::prelude::v1`]。 68 | 69 | 在根 crate 模块上,通过使用 `no_std` 70 | [属性][attribute],prelude 可被变更为 *core prelude*。其链接的 crate 是 [`core`],prelude 模块是 [`core::prelude::v1`]。当 crate 的目标平台不支持标准库或因一些原因不使用标准库的功能时,使用核心 prelude 而不是标准 prelude 会非常有用。这些功能主要是用在动态内存分配(例如 `Box` 和 `Vec`),以及文件和网络功能( 71 | `std::fs` 和 `std::io`)。 72 | 73 |
74 | 75 | 警告:使用 `no_std` 不会阻止对标准库的链接。`extern crate std;` 在 crate 仍然会有效执行,并且依赖项也可以链接到 crate 中。 76 | 77 |
78 | 79 | ## 主要功能 80 | 81 | 包含 `main` [函数][function]的 crate 可以被编译为可执行文件。如果存在 82 | `main` 函数,则其必须不带参数,不得声明任何 [trait 或生命周期边界][trait or lifetime bounds],不得具有任何 [where 子句][where clauses],并且其返回类型必须为以下类型之一: 83 | 84 | * `()` 85 | * `Result<(), E> where E: Error` 86 | 87 | 88 | 89 | > 注意:允许哪些返回类型的实现,是由暂未稳定的 [`Termination`] trait 决定的。 90 | 91 | 92 | 93 | ### `no_main` 属性 94 | 95 | 在 crate 层级,可应用 [*`no_main` 属性*][attribute] 来禁止对可执行二进制文件发出 `main` 符号——即禁止 `main` 函数的执行。当链接到的其他对象定义了 `main` 函数时,若要禁止这些连接到的对象 crate 的执行,`no_main` 属性将很有用。 96 | 97 | ## `crate_name` 属性 98 | 99 | [*`crate_name` 属性*][attribute] 可以应用于 crate 层级,以使用 [_MetaNameValueStr_] 语法指定 crate 的名称。 100 | 101 | ```rust 102 | #![crate_name = "mycrate"] 103 | ``` 104 | 105 | crate 名称不能为空,并且只能包含 [Unicode 字母、数字][Unicode alphanumeric],或 `-`(U+002D)字符。 106 | 107 | [^阶段区别]:这种区别也存在于解释器中。静态检查(如语法分析、类型检查和 lints)应该在程序执行之前进行,而不管它是何时执行的。 108 | 109 | [^crate 源文件]:crate 有点类似于 ECMA-335 CLI 模型中的 *汇编*、SML/NJ 编译管理器中的 *库*、Owens 和 Flatt 模块系统中的 *单元*,或 Mesa 中的 *配置*。 110 | 111 | [Unicode alphanumeric]: ../std/primitive.char.html#method.is_alphanumeric 112 | [_InnerAttribute_]: attributes.md 113 | [_Item_]: items.md 114 | [_MetaNameValueStr_]: attributes.md#meta-item-attribute-syntax 115 | [_shebang_]: https://en.wikipedia.org/wiki/Shebang_(Unix) 116 | [_utf8 byte order mark_]: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8 117 | [`Termination`]: ../std/process/trait.Termination.html 118 | [`core`]: ../core/index.html 119 | [`core::prelude::v1`]: ../core/prelude/index.html 120 | [`extern crate`]: items/extern-crates.md 121 | [`std`]: ../std/index.html 122 | [`std::prelude::v1`]: ../std/prelude/index.html 123 | [attribute]: attributes.md 124 | [attributes]: attributes.md 125 | [comments]: comments.md 126 | [function]: items/functions.md 127 | [module]: items/modules.md 128 | [module path]: paths.md 129 | [trait or lifetime bounds]: trait-bounds.md 130 | [where clauses]: items/generics.md#where-clauses 131 | [whitespace]: whitespace.md 132 | -------------------------------------------------------------------------------- /src/css/reference.css: -------------------------------------------------------------------------------- 1 | /* 2 | .parenthetical class used to keep e.g. "less-than symbol (<)" from wrapping 3 | the end parenthesis onto its own line. Use in a span between the last word and 4 | the parenthetical. So for this example, you'd use 5 | ```less-than symbol (`<`)``` 6 | */ 7 | .parenthetical { 8 | white-space: nowrap; 9 | } 10 | 11 | /* 12 | Warnings and notes: 13 | 14 | Write the
s on their own line. E.g. 15 | 16 |
17 | 18 | Warning: This is bad! 19 | 20 |
21 | */ 22 | main .warning p { 23 | padding: 10px 20px; 24 | margin: 20px 0; 25 | } 26 | 27 | main .warning p::before { 28 | content: "⚠️ "; 29 | } 30 | 31 | .light main .warning p, 32 | .rust main .warning p { 33 | border: 2px solid red; 34 | background: #ffcece; 35 | } 36 | 37 | .rust main .warning p { 38 | /* overrides previous declaration */ 39 | border-color: #961717; 40 | } 41 | 42 | .coal main .warning p, 43 | .navy main .warning p, 44 | .ayu main .warning p { 45 | background: #542626 46 | } 47 | 48 | /* Make the links higher contrast on dark themes */ 49 | .coal main .warning p a, 50 | .navy main .warning p a, 51 | .ayu main .warning p a { 52 | color: #80d0d0 53 | } 54 | -------------------------------------------------------------------------------- /src/css/summary.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzy/rust-reference-zh-cn/02d06fa67b9760580e11f27baa7edf054a264d04/src/css/summary.jpg -------------------------------------------------------------------------------- /src/destructors.md: -------------------------------------------------------------------------------- 1 | # Destructors 2 | 3 | When an [initialized] [variable] in Rust goes out of scope or a [temporary] 4 | is no longer needed its _destructor_ is run. [Assignment] also runs the 5 | destructor of its left-hand operand, unless it's an uninitialized variable. If a 6 | [struct] variable has been partially initialized, only its initialized fields 7 | are dropped. 8 | 9 | The destructor of a type consists of 10 | 11 | 1. Calling its [`std::ops::Drop::drop`] method, if it has one. 12 | 2. Recursively running the destructor of all of its fields. 13 | * The fields of a [struct], [tuple] or [enum variant] are dropped in 14 | declaration order. \* 15 | * The elements of an [array] or owned [slice][array] are dropped from the 16 | first element to the last. \* 17 | * The captured values of a [closure] are dropped in an unspecified order. 18 | * [Trait objects] run the destructor of the underlying type. 19 | * Other types don't result in any further drops. 20 | 21 | \* This order was stabilized in [RFC 1857]. 22 | 23 | Variables are dropped in reverse order of declaration. Variables declared in 24 | the same pattern drop in an unspecified ordered. 25 | 26 | If a destructor must be run manually, such as when implementing your own smart 27 | pointer, [`std::ptr::drop_in_place`] can be used. 28 | 29 | Some examples: 30 | 31 | ```rust 32 | struct ShowOnDrop(&'static str); 33 | 34 | impl Drop for ShowOnDrop { 35 | fn drop(&mut self) { 36 | println!("{}", self.0); 37 | } 38 | } 39 | 40 | { 41 | let mut overwritten = ShowOnDrop("Drops when overwritten"); 42 | overwritten = ShowOnDrop("drops when scope ends"); 43 | } 44 | # println!(""); 45 | { 46 | let declared_first = ShowOnDrop("Dropped last"); 47 | let declared_last = ShowOnDrop("Dropped first"); 48 | } 49 | # println!(""); 50 | { 51 | // Tuple elements drop in forwards order 52 | let tuple = (ShowOnDrop("Tuple first"), ShowOnDrop("Tuple second")); 53 | } 54 | # println!(""); 55 | loop { 56 | // Tuple expression doesn't finish evaluating so temporaries drop in reverse order: 57 | let partial_tuple = (ShowOnDrop("Temp first"), ShowOnDrop("Temp second"), break); 58 | } 59 | # println!(""); 60 | { 61 | let moved; 62 | // No destructor run on assignment. 63 | moved = ShowOnDrop("Drops when moved"); 64 | // drops now, but is then uninitialized 65 | moved; 66 | 67 | // Uninitialized does not drop. 68 | let uninitialized: ShowOnDrop; 69 | 70 | // After a partial move, only the remaining fields are dropped. 71 | let mut partial_move = (ShowOnDrop("first"), ShowOnDrop("forgotten")); 72 | // Perform a partial move, leaving only `partial_move.0` initialized. 73 | core::mem::forget(partial_move.1); 74 | // When partial_move's scope ends, only the first field is dropped. 75 | } 76 | ``` 77 | 78 | ## Not running destructors 79 | 80 | Not running destructors in Rust is safe even if it has a type that isn't 81 | `'static`. [`std::mem::ManuallyDrop`] provides a wrapper to prevent a 82 | variable or field from being dropped automatically. 83 | 84 | [initialized]: glossary.md#initialized 85 | [variable]: variables.md 86 | [temporary]: expressions.md#temporary-lifetimes 87 | [Assignment]: expressions/operator-expr.md#assignment-expressions 88 | [`std::ops::Drop::drop`]: ../std/ops/trait.Drop.html 89 | [RFC 1857]: https://github.com/rust-lang/rfcs/blob/master/text/1857-stabilize-drop-order.md 90 | [struct]: types/struct.md 91 | [tuple]: types/tuple.md 92 | [enum variant]: types/enum.md 93 | [array]: types/array.md 94 | [closure]: types/closure.md 95 | [Trait objects]: types/trait-object.md 96 | [`std::ptr::drop_in_place`]: ../std/ptr/fn.drop_in_place.html 97 | [`std::mem::ManuallyDrop`]: ../std/mem/struct.ManuallyDrop.html 98 | -------------------------------------------------------------------------------- /src/dynamically-sized-types.md: -------------------------------------------------------------------------------- 1 | # Dynamically Sized Types 2 | 3 | Most types have a fixed size that is known at compile time and implement the 4 | trait [`Sized`][sized]. A type with a size that is known only at run-time is 5 | called a _dynamically sized type_ (_DST_) or, informally, an unsized type. 6 | [Slices] and [trait objects] are two examples of DSTs. Such types can only be used in certain cases: 8 | 9 | * [Pointer types] to DSTs are 10 | sized but have twice the size of pointers to sized types 11 | * Pointers to slices also store the number of elements of the slice. 12 | * Pointers to trait objects also store a pointer to a vtable. 13 | * DSTs can be provided as 14 | type arguments when a bound of `?Sized`. By default any type parameter 15 | has a `Sized` bound. 16 | * Traits may be implemented for DSTs. Unlike type parameters `Self: ?Sized` by default in trait 18 | definitions. 19 | * Structs may contain a DST as the 20 | last field, this makes the struct itself a 21 | DST. 22 | 23 | > **Note**: [variables], function parameters, [const] items, and [static] items must be 24 | `Sized`. 25 | 26 | [sized]: special-types-and-traits.md#sized 27 | [Slices]: types/slice.md 28 | [trait objects]: types/trait-object.md 29 | [Pointer types]: types/pointer.md 30 | [variables]: variables.md 31 | [const]: items/constant-items.md 32 | [static]: items/static-items.md 33 | -------------------------------------------------------------------------------- /src/expressions/array-expr.md: -------------------------------------------------------------------------------- 1 | # Array and array index expressions 2 | 3 | ## Array expressions 4 | 5 | > **Syntax**\ 6 | > _ArrayExpression_ :\ 7 | >    `[` [_InnerAttribute_]\* _ArrayElements_? `]` 8 | > 9 | > _ArrayElements_ :\ 10 | >       [_Expression_] ( `,` [_Expression_] )\* `,`?\ 11 | >    | [_Expression_] `;` [_Expression_] 12 | 13 | An _[array](../types/array.md) expression_ can be written by 14 | enclosing zero or more comma-separated expressions of uniform type in square 15 | brackets. This produces an array containing each of these values in the 16 | order they are written. 17 | 18 | Alternatively there can be exactly two expressions inside the brackets, 19 | separated by a semi-colon. The expression after the `;` must be a have type 20 | `usize` and be a [constant expression], 21 | such as a [literal](../tokens.md#literals) or a [constant 22 | item](../items/constant-items.md). `[a; b]` creates an array containing `b` 23 | copies of the value of `a`. If the expression after the semi-colon has a value 24 | greater than 1 then this requires that the type of `a` is 25 | [`Copy`](../special-types-and-traits.md#copy). 26 | 27 | ```rust 28 | [1, 2, 3, 4]; 29 | ["a", "b", "c", "d"]; 30 | [0; 128]; // array with 128 zeros 31 | [0u8, 0u8, 0u8, 0u8,]; 32 | [[1, 0, 0], [0, 1, 0], [0, 0, 1]]; // 2D array 33 | ``` 34 | 35 | ### Array expression attributes 36 | 37 | [Inner attributes] are allowed directly after the opening bracket of an array 38 | expression in the same expression contexts as [attributes on block 39 | expressions]. 40 | 41 | ## Array and slice indexing expressions 42 | 43 | > **Syntax**\ 44 | > _IndexExpression_ :\ 45 | >    [_Expression_] `[` [_Expression_] `]` 46 | 47 | [Array](../types/array.md) and [slice](../types/slice.md)-typed expressions can be 48 | indexed by writing a square-bracket-enclosed expression of type `usize` (the 49 | index) after them. When the array is mutable, the resulting [memory location] 50 | can be assigned to. 51 | 52 | For other types an index expression `a[b]` is equivalent to 53 | `*std::ops::Index::index(&a, b)`, or 54 | `*std::ops::IndexMut::index_mut(&mut a, b)` in a mutable place expression 55 | context. Just as with methods, Rust will also insert dereference operations on 56 | `a` repeatedly to find an implementation. 57 | 58 | Indices are zero-based for arrays and slices. Array access is a [constant 59 | expression], so bounds can be checked at compile-time with a constant index 60 | value. Otherwise a check will be performed at run-time that will put the thread 61 | in a _panicked state_ if it fails. 62 | 63 | ```rust,should_panic 64 | // lint is deny by default. 65 | #![warn(unconditional_panic)] 66 | 67 | ([1, 2, 3, 4])[2]; // Evaluates to 3 68 | 69 | let b = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]; 70 | b[1][2]; // multidimensional array indexing 71 | 72 | let x = (["a", "b"])[10]; // warning: index out of bounds 73 | 74 | let n = 10; 75 | let y = (["a", "b"])[n]; // panics 76 | 77 | let arr = ["a", "b"]; 78 | arr[10]; // warning: index out of bounds 79 | ``` 80 | 81 | The array index expression can be implemented for types other than arrays and slices 82 | by implementing the [Index] and [IndexMut] traits. 83 | 84 | [IndexMut]: ../../std/ops/trait.IndexMut.html 85 | [Index]: ../../std/ops/trait.Index.html 86 | [Inner attributes]: ../attributes.md 87 | [_Expression_]: ../expressions.md 88 | [_InnerAttribute_]: ../attributes.md 89 | [attributes on block expressions]: block-expr.md#attributes-on-block-expressions 90 | [constant expression]: ../const_eval.md#constant-expressions 91 | [memory location]: ../expressions.md#place-expressions-and-value-expressions 92 | -------------------------------------------------------------------------------- /src/expressions/await-expr.md: -------------------------------------------------------------------------------- 1 | # Await expressions 2 | 3 | > **Syntax**\ 4 | > _AwaitExpression_ :\ 5 | >    [_Expression_] `.` `await` 6 | 7 | Await expressions are legal only within an [async context], like an 8 | [`async fn`] or an [`async` block]. They operate on a [future]. Their effect 9 | is to suspend the current computation until the given future is ready 10 | to produce a value. 11 | 12 | More specifically, an `.await` expression has the following effect. 13 | 14 | 1. Evaluate `` to a [future] `tmp`; 15 | 2. Pin `tmp` using [`Pin::new_unchecked`]; 16 | 3. This pinned future is then polled by calling the [`Future::poll`] method and 17 | passing it the current [task context](#task-context); 18 | 3. If the call to `poll` returns [`Poll::Pending`], then the future 19 | returns `Poll::Pending`, suspending its state so that, when the 20 | surrounding async context is re-polled, execution returns to step 21 | 2; 22 | 4. Otherwise the call to `poll` must have returned [`Poll::Ready`], in which case the 23 | value contained in the [`Poll::Ready`] variant is used as the result 24 | of the `await` expression itself. 25 | 26 | [`async fn`]: ../items/functions.md#async-functions 27 | [`async` block]: block-expr.md#async-blocks 28 | [future]: ../../std/future/trait.Future.html 29 | [_Expression_]: ../expressions.md 30 | [`Future::poll`]: ../../std/future/trait.Future.html#tymethod.poll 31 | [`Context`]: ../../std/task/struct.Context.html 32 | [`Pin::new_unchecked`]: ../../std/pin/struct.Pin.html#method.new_unchecked 33 | [`Poll::Pending`]: ../../std/task/enum.Poll.html#variant.Pending 34 | [`Poll::Ready`]: ../../std/task/enum.Poll.html#variant.Ready 35 | 36 | > **Edition differences**: Await expressions are only available beginning with 37 | > Rust 2018. 38 | 39 | ## Task context 40 | 41 | The task context refers to the [`Context`] which was supplied to the 42 | current [async context] when the async context itself was 43 | polled. Because `await` expressions are only legal in an async 44 | context, there must be some task context available. 45 | 46 | [`Context`]: ../../std/task/struct.Context.html 47 | [async context]: ../expressions/block-expr.md#async-context 48 | 49 | ## Approximate desugaring 50 | 51 | Effectively, an `.await` expression is roughly 52 | equivalent to the following (this desugaring is not normative): 53 | 54 | 55 | ```rust,ignore 56 | match /* */ { 57 | mut pinned => loop { 58 | let mut pin = unsafe { Pin::new_unchecked(&mut pinned) }; 59 | match Pin::future::poll(Pin::borrow(&mut pin), &mut current_context) { 60 | Poll::Ready(r) => break r, 61 | Poll::Pending => yield Poll::Pending, 62 | } 63 | } 64 | } 65 | ``` 66 | 67 | where the `yield` pseudo-code returns `Poll::Pending` and, when 68 | re-invoked, resumes execution from that point. The variable 69 | `current_context` refers to the context taken from the async 70 | environment. 71 | -------------------------------------------------------------------------------- /src/expressions/call-expr.md: -------------------------------------------------------------------------------- 1 | # Call expressions 2 | 3 | > **Syntax**\ 4 | > _CallExpression_ :\ 5 | >    [_Expression_] `(` _CallParams_? `)` 6 | > 7 | > _CallParams_ :\ 8 | >    [_Expression_] ( `,` [_Expression_] )\* `,`? 9 | 10 | A _call expression_ consists of an expression followed by a parenthesized 11 | expression-list. It invokes a function, providing zero or more input variables. 12 | If the function eventually returns, then the expression completes. For 13 | [non-function types](../types/function-item.md), the expression f(...) uses 14 | the method on one of the [`std::ops::Fn`], [`std::ops::FnMut`] or 15 | [`std::ops::FnOnce`] traits, which differ in whether they take the type by 16 | reference, mutable reference, or take ownership respectively. An automatic 17 | borrow will be taken if needed. Rust will also automatically dereference `f` as 18 | required. Some examples of call expressions: 19 | 20 | ```rust 21 | # fn add(x: i32, y: i32) -> i32 { 0 } 22 | let three: i32 = add(1i32, 2i32); 23 | let name: &'static str = (|| "Rust")(); 24 | ``` 25 | 26 | ## Disambiguating Function Calls 27 | 28 | Rust treats all function calls as sugar for a more explicit, fully-qualified 29 | syntax. Upon compilation, Rust will desugar all function calls into the explicit 30 | form. Rust may sometimes require you to qualify function calls with trait, 31 | depending on the ambiguity of a call in light of in-scope items. 32 | 33 | > **Note**: In the past, the Rust community used the terms "Unambiguous 34 | > Function Call Syntax", "Universal Function Call Syntax", or "UFCS", in 35 | > documentation, issues, RFCs, and other community writings. However, the term 36 | > lacks descriptive power and potentially confuses the issue at hand. We mention 37 | > it here for searchability's sake. 38 | 39 | Several situations often occur which result in ambiguities about the receiver or 40 | referent of method or associated function calls. These situations may include: 41 | 42 | * Multiple in-scope traits define methods with the same name for the same types 43 | * Auto-`deref` is undesirable; for example, distinguishing between methods on a 44 | smart pointer itself and the pointer's referent 45 | * Methods which take no arguments, like `default()`, and return properties of a 46 | type, like `size_of()` 47 | 48 | To resolve the ambiguity, the programmer may refer to their desired method or 49 | function using more specific paths, types, or traits. 50 | 51 | For example, 52 | 53 | ```rust 54 | trait Pretty { 55 | fn print(&self); 56 | } 57 | 58 | trait Ugly { 59 | fn print(&self); 60 | } 61 | 62 | struct Foo; 63 | impl Pretty for Foo { 64 | fn print(&self) {} 65 | } 66 | 67 | struct Bar; 68 | impl Pretty for Bar { 69 | fn print(&self) {} 70 | } 71 | impl Ugly for Bar{ 72 | fn print(&self) {} 73 | } 74 | 75 | fn main() { 76 | let f = Foo; 77 | let b = Bar; 78 | 79 | // we can do this because we only have one item called `print` for `Foo`s 80 | f.print(); 81 | // more explicit, and, in the case of `Foo`, not necessary 82 | Foo::print(&f); 83 | // if you're not into the whole brevity thing 84 | ::print(&f); 85 | 86 | // b.print(); // Error: multiple 'print' found 87 | // Bar::print(&b); // Still an error: multiple `print` found 88 | 89 | // necessary because of in-scope items defining `print` 90 | ::print(&b); 91 | } 92 | ``` 93 | 94 | Refer to [RFC 132] for further details and motivations. 95 | 96 | [`std::ops::Fn`]: ../../std/ops/trait.Fn.html 97 | [`std::ops::FnMut`]: ../../std/ops/trait.FnMut.html 98 | [`std::ops::FnOnce`]: ../../std/ops/trait.FnOnce.html 99 | [RFC 132]: https://github.com/rust-lang/rfcs/blob/master/text/0132-ufcs.md 100 | 101 | [_Expression_]: ../expressions.md 102 | -------------------------------------------------------------------------------- /src/expressions/closure-expr.md: -------------------------------------------------------------------------------- 1 | # Closure expressions 2 | 3 | > **Syntax**\ 4 | > _ClosureExpression_ :\ 5 | >    `move`?\ 6 | >    ( `||` | `|` _ClosureParameters_? `|` )\ 7 | >    ([_Expression_] | `->` [_TypeNoBounds_] [_BlockExpression_]) 8 | > 9 | > _ClosureParameters_ :\ 10 | >    _ClosureParam_ (`,` _ClosureParam_)\* `,`? 11 | > 12 | > _ClosureParam_ :\ 13 | >    [_OuterAttribute_]\* [_Pattern_] ( `:` [_Type_] )? 14 | 15 | A _closure expression_, also know as a lambda expression or a lambda, defines a 16 | closure and denotes it as a value, in a single expression. A closure expression 17 | is a pipe-symbol-delimited (`|`) list of irrefutable [patterns] followed by an 18 | expression. Type annotations may optionally be added for the type of the 19 | parameters or for the return type. If there is a return type, the expression 20 | used for the body of the closure must be a normal [block]. A closure expression 21 | also may begin with the `move` keyword before the initial `|`. 22 | 23 | A closure expression denotes a function that maps a list of parameters onto 24 | the expression that follows the parameters. Just like a [`let` binding], the 25 | parameters are irrefutable [patterns], whose type annotation is optional and 26 | will be inferred from context if not given. Each closure expression has a 27 | unique, anonymous type. 28 | 29 | Closure expressions are most useful when passing functions as arguments to other 30 | functions, as an abbreviation for defining and capturing a separate function. 31 | 32 | Significantly, closure expressions _capture their environment_, which regular 33 | [function definitions] do not. Without the `move` keyword, the closure expression 34 | [infers how it captures each variable from its environment](../types/closure.md#capture-modes), 35 | preferring to capture by shared reference, effectively borrowing 36 | all outer variables mentioned inside the closure's body. If needed the compiler 37 | will infer that instead mutable references should be taken, or that the values 38 | should be moved or copied (depending on their type) from the environment. A 39 | closure can be forced to capture its environment by copying or moving values by 40 | prefixing it with the `move` keyword. This is often used to ensure that the 41 | closure's type is `'static`. 42 | 43 | The compiler will determine which of the [closure 44 | traits](../types/closure.md#call-traits-and-coercions) the closure's type will implement by how it 45 | acts on its captured variables. The closure will also implement 46 | [`Send`](../special-types-and-traits.md#send) and/or 47 | [`Sync`](../special-types-and-traits.md#sync) if all of its captured types do. 48 | These traits allow functions to accept closures using generics, even though the 49 | exact types can't be named. 50 | 51 | In this example, we define a function `ten_times` that takes a higher-order 52 | function argument, and we then call it with a closure expression as an argument, 53 | followed by a closure expression that moves values from its environment. 54 | 55 | ```rust 56 | fn ten_times(f: F) where F: Fn(i32) { 57 | for index in 0..10 { 58 | f(index); 59 | } 60 | } 61 | 62 | ten_times(|j| println!("hello, {}", j)); 63 | // With type annotations 64 | ten_times(|j: i32| -> () { println!("hello, {}", j) }); 65 | 66 | let word = "konnichiwa".to_owned(); 67 | ten_times(move |j| println!("{}, {}", word, j)); 68 | ``` 69 | 70 | ## Attributes on closure parameters 71 | 72 | Attributes on closure parameters follow the same rules and restrictions as 73 | [regular function parameters]. 74 | 75 | [block]: block-expr.md 76 | [function definitions]: ../items/functions.md 77 | [patterns]: ../patterns.md 78 | [regular function parameters]: ../items/functions.md#attributes-on-function-parameters 79 | 80 | [_Expression_]: ../expressions.md 81 | [_BlockExpression_]: block-expr.md 82 | [_TypeNoBounds_]: ../types.md#type-expressions 83 | [_Pattern_]: ../patterns.md 84 | [_Type_]: ../types.md#type-expressions 85 | [`let` binding]: ../statements.md#let-statements 86 | [_OuterAttribute_]: ../attributes.md 87 | -------------------------------------------------------------------------------- /src/expressions/enum-variant-expr.md: -------------------------------------------------------------------------------- 1 | # Enumeration Variant expressions 2 | 3 | > **Syntax**\ 4 | > _EnumerationVariantExpression_ :\ 5 | >       _EnumExprStruct_\ 6 | >    | _EnumExprTuple_\ 7 | >    | _EnumExprFieldless_ 8 | > 9 | > _EnumExprStruct_ :\ 10 | >    [_PathInExpression_] `{` _EnumExprFields_? `}` 11 | > 12 | > _EnumExprFields_ :\ 13 | >       _EnumExprField_ (`,` _EnumExprField_)\* `,`? 14 | > 15 | > _EnumExprField_ :\ 16 | >       [IDENTIFIER]\ 17 | >    | ([IDENTIFIER] | [TUPLE_INDEX]) `:` [_Expression_] 18 | > 19 | > _EnumExprTuple_ :\ 20 | >    [_PathInExpression_] `(`\ 21 | >       ( [_Expression_] (`,` [_Expression_])\* `,`? )?\ 22 | >    `)` 23 | > 24 | > _EnumExprFieldless_ : [_PathInExpression_] 25 | 26 | Enumeration variants can be constructed similarly to [structs], using a path to an enum 27 | variant instead of to a struct: 28 | 29 | ```rust 30 | # enum Message { 31 | # Quit, 32 | # WriteString(String), 33 | # Move { x: i32, y: i32 }, 34 | # } 35 | let q = Message::Quit; 36 | let w = Message::WriteString("Some string".to_string()); 37 | let m = Message::Move { x: 50, y: 200 }; 38 | ``` 39 | 40 | Enum variant expressions have the same syntax, behavior, and restrictions as [struct 41 | expressions][structs], except they do not support base update with the `..` syntax. 42 | 43 | [IDENTIFIER]: ../identifiers.md 44 | [TUPLE_INDEX]: ../tokens.md#integer-literals 45 | [_Expression_]: ../expressions.md 46 | [_PathInExpression_]: ../paths.md#paths-in-expressions 47 | [structs]: struct-expr.md 48 | -------------------------------------------------------------------------------- /src/expressions/field-expr.md: -------------------------------------------------------------------------------- 1 | # Field access expressions 2 | 3 | > **Syntax**\ 4 | > _FieldExpression_ :\ 5 | >    [_Expression_] `.` [IDENTIFIER] 6 | 7 | A _field expression_ consists of an expression followed by a single dot and an 8 | [identifier], when not immediately followed by a parenthesized expression-list 9 | (the latter is always a [method call expression]). A field expression denotes a 10 | field of a [struct] or [union]. To call a function stored in a struct, 11 | parentheses are needed around the field expression. 12 | 13 | 14 | ```rust,ignore 15 | mystruct.myfield; 16 | foo().x; 17 | (Struct {a: 10, b: 20}).a; 18 | mystruct.method(); // Method expression 19 | (mystruct.function_field)() // Call expression containing a field expression 20 | ``` 21 | 22 | A field access is a [place expression] referring to the location of that field. 23 | When the subexpression is [mutable], the field expression is also mutable. 24 | 25 | Also, if the type of the expression to the left of the dot is a pointer, it is 26 | automatically dereferenced as many times as necessary to make the field access 27 | possible. In cases of ambiguity, we prefer fewer autoderefs to more. 28 | 29 | Finally, the fields of a struct or a reference to a struct are treated as 30 | separate entities when borrowing. If the struct does not implement 31 | [`Drop`](../special-types-and-traits.md#drop) and is stored in a local variable, 32 | this also applies to moving out of each of its fields. This also does not apply 33 | if automatic dereferencing is done though user defined types. 34 | 35 | ```rust 36 | struct A { f1: String, f2: String, f3: String } 37 | let mut x: A; 38 | # x = A { 39 | # f1: "f1".to_string(), 40 | # f2: "f2".to_string(), 41 | # f3: "f3".to_string() 42 | # }; 43 | let a: &mut String = &mut x.f1; // x.f1 borrowed mutably 44 | let b: &String = &x.f2; // x.f2 borrowed immutably 45 | let c: &String = &x.f2; // Can borrow again 46 | let d: String = x.f3; // Move out of x.f3 47 | ``` 48 | 49 | [_Expression_]: ../expressions.md 50 | [IDENTIFIER]: ../identifiers.md 51 | [method call expression]: method-call-expr.md 52 | [struct]: ../items/structs.md 53 | [union]: ../items/unions.md 54 | [place expression]: ../expressions.md#place-expressions-and-value-expressions 55 | [mutable]: ../expressions.md#mutability 56 | -------------------------------------------------------------------------------- /src/expressions/grouped-expr.md: -------------------------------------------------------------------------------- 1 | # Grouped expressions 2 | 3 | > **Syntax**\ 4 | > _GroupedExpression_ :\ 5 | >    `(` [_InnerAttribute_]\* [_Expression_] `)` 6 | 7 | An expression enclosed in parentheses evaluates to the result of the enclosed 8 | expression. Parentheses can be used to explicitly specify evaluation order 9 | within an expression. 10 | 11 | An example of a parenthesized expression: 12 | 13 | ```rust 14 | let x: i32 = 2 + 3 * 4; 15 | let y: i32 = (2 + 3) * 4; 16 | assert_eq!(x, 14); 17 | assert_eq!(y, 20); 18 | ``` 19 | 20 | An example of a necessary use of parentheses is when calling a function pointer 21 | that is a member of a struct: 22 | 23 | ```rust 24 | # struct A { 25 | # f: fn() -> &'static str 26 | # } 27 | # impl A { 28 | # fn f(&self) -> &'static str { 29 | # "The method f" 30 | # } 31 | # } 32 | # let a = A{f: || "The field f"}; 33 | # 34 | assert_eq!( a.f (), "The method f"); 35 | assert_eq!((a.f)(), "The field f"); 36 | ``` 37 | 38 | ## Group expression attributes 39 | 40 | [Inner attributes] are allowed directly after the opening parenthesis of a 41 | group expression in the same expression contexts as [attributes on block 42 | expressions]. 43 | 44 | [Inner attributes]: ../attributes.md 45 | [_Expression_]: ../expressions.md 46 | [_InnerAttribute_]: ../attributes.md 47 | [attributes on block expressions]: block-expr.md#attributes-on-block-expressions 48 | -------------------------------------------------------------------------------- /src/expressions/if-expr.md: -------------------------------------------------------------------------------- 1 | # `if` and `if let` expressions 2 | 3 | ## `if` expressions 4 | 5 | > **Syntax**\ 6 | > _IfExpression_ :\ 7 | >    `if` [_Expression_]_except struct expression_ [_BlockExpression_]\ 8 | >    (`else` ( 9 | > [_BlockExpression_] 10 | > | _IfExpression_ 11 | > | _IfLetExpression_ ) )\? 12 | 13 | An `if` expression is a conditional branch in program control. The form of an 14 | `if` expression is a condition expression, followed by a consequent block, any 15 | number of `else if` conditions and blocks, and an optional trailing `else` 16 | block. The condition expressions must have type `bool`. If a condition 17 | expression evaluates to `true`, the consequent block is executed and any 18 | subsequent `else if` or `else` block is skipped. If a condition expression 19 | evaluates to `false`, the consequent block is skipped and any subsequent `else 20 | if` condition is evaluated. If all `if` and `else if` conditions evaluate to 21 | `false` then any `else` block is executed. An if expression evaluates to the 22 | same value as the executed block, or `()` if no block is evaluated. An `if` 23 | expression must have the same type in all situations. 24 | 25 | ```rust 26 | # let x = 3; 27 | if x == 4 { 28 | println!("x is four"); 29 | } else if x == 3 { 30 | println!("x is three"); 31 | } else { 32 | println!("x is something else"); 33 | } 34 | 35 | let y = if 12 * 15 > 150 { 36 | "Bigger" 37 | } else { 38 | "Smaller" 39 | }; 40 | assert_eq!(y, "Bigger"); 41 | ``` 42 | 43 | ## `if let` expressions 44 | 45 | > **Syntax**\ 46 | > _IfLetExpression_ :\ 47 | >    `if` `let` [_MatchArmPatterns_] `=` [_Expression_]_except struct or lazy boolean operator expression_ 48 | > [_BlockExpression_]\ 49 | >    (`else` ( 50 | > [_BlockExpression_] 51 | > | _IfExpression_ 52 | > | _IfLetExpression_ ) )\? 53 | 54 | An `if let` expression is semantically similar to an `if` expression but in 55 | place of a condition expression it expects the keyword `let` followed by a 56 | pattern, an `=` and a [scrutinee] expression. If the value of the scrutinee 57 | matches the pattern, the corresponding block will execute. Otherwise, flow 58 | proceeds to the following `else` block if it exists. Like `if` expressions, 59 | `if let` expressions have a value determined by the block that is evaluated. 60 | 61 | ```rust 62 | let dish = ("Ham", "Eggs"); 63 | 64 | // this body will be skipped because the pattern is refuted 65 | if let ("Bacon", b) = dish { 66 | println!("Bacon is served with {}", b); 67 | } else { 68 | // This block is evaluated instead. 69 | println!("No bacon will be served"); 70 | } 71 | 72 | // this body will execute 73 | if let ("Ham", b) = dish { 74 | println!("Ham is served with {}", b); 75 | } 76 | 77 | if let _ = 5 { 78 | println!("Irrefutable patterns are always true"); 79 | } 80 | ``` 81 | 82 | `if` and `if let` expressions can be intermixed: 83 | 84 | ```rust 85 | let x = Some(3); 86 | let a = if let Some(1) = x { 87 | 1 88 | } else if x == Some(2) { 89 | 2 90 | } else if let Some(y) = x { 91 | y 92 | } else { 93 | -1 94 | }; 95 | assert_eq!(a, 3); 96 | ``` 97 | 98 | An `if let` expression is equivalent to a [`match` expression] as follows: 99 | 100 | 101 | ```rust,ignore 102 | if let PATS = EXPR { 103 | /* body */ 104 | } else { 105 | /*else */ 106 | } 107 | ``` 108 | 109 | is equivalent to 110 | 111 | 112 | ```rust,ignore 113 | match EXPR { 114 | PATS => { /* body */ }, 115 | _ => { /* else */ }, // () if there is no else 116 | } 117 | ``` 118 | 119 | Multiple patterns may be specified with the `|` operator. This has the same semantics 120 | as with `|` in `match` expressions: 121 | 122 | ```rust 123 | enum E { 124 | X(u8), 125 | Y(u8), 126 | Z(u8), 127 | } 128 | let v = E::Y(12); 129 | if let E::X(n) | E::Y(n) = v { 130 | assert_eq!(n, 12); 131 | } 132 | ``` 133 | 134 | The expression cannot be a [lazy boolean operator expression][_LazyBooleanOperatorExpression_]. 135 | Use of a lazy boolean operator is ambiguous with a planned feature change 136 | of the language (the implementation of if-let chains - see [eRFC 2947][_eRFCIfLetChain_]). 137 | When lazy boolean operator expression is desired, this can be achieved 138 | by using parenthesis as below: 139 | 140 | 141 | ```rust,ignore 142 | // Before... 143 | if let PAT = EXPR && EXPR { .. } 144 | 145 | // After... 146 | if let PAT = ( EXPR && EXPR ) { .. } 147 | 148 | // Before... 149 | if let PAT = EXPR || EXPR { .. } 150 | 151 | // After... 152 | if let PAT = ( EXPR || EXPR ) { .. } 153 | ``` 154 | 155 | [_BlockExpression_]: block-expr.md 156 | [_Expression_]: ../expressions.md 157 | [_LazyBooleanOperatorExpression_]: operator-expr.md#lazy-boolean-operators 158 | [_MatchArmPatterns_]: match-expr.md 159 | [_eRFCIfLetChain_]: https://github.com/rust-lang/rfcs/blob/master/text/2497-if-let-chains.md#rollout-plan-and-transitioning-to-rust-2018 160 | [`match` expression]: match-expr.md 161 | [scrutinee]: ../glossary.md#scrutinee 162 | -------------------------------------------------------------------------------- /src/expressions/literal-expr.md: -------------------------------------------------------------------------------- 1 | # Literal expressions 2 | 3 | > **Syntax**\ 4 | > _LiteralExpression_ :\ 5 | >       [CHAR_LITERAL]\ 6 | >    | [STRING_LITERAL]\ 7 | >    | [RAW_STRING_LITERAL]\ 8 | >    | [BYTE_LITERAL]\ 9 | >    | [BYTE_STRING_LITERAL]\ 10 | >    | [RAW_BYTE_STRING_LITERAL]\ 11 | >    | [INTEGER_LITERAL]\ 12 | >    | [FLOAT_LITERAL]\ 13 | >    | [BOOLEAN_LITERAL] 14 | 15 | A _literal expression_ consists of one of the [literal](../tokens.md#literals) 16 | forms described earlier. It directly describes a number, character, string, 17 | or boolean value. 18 | 19 | ```rust 20 | "hello"; // string type 21 | '5'; // character type 22 | 5; // integer type 23 | ``` 24 | 25 | [CHAR_LITERAL]: ../tokens.md#character-literals 26 | [STRING_LITERAL]: ../tokens.md#string-literals 27 | [RAW_STRING_LITERAL]: ../tokens.md#raw-string-literals 28 | [BYTE_LITERAL]: ../tokens.md#byte-literals 29 | [BYTE_STRING_LITERAL]: ../tokens.md#byte-string-literals 30 | [RAW_BYTE_STRING_LITERAL]: ../tokens.md#raw-byte-string-literals 31 | [INTEGER_LITERAL]: ../tokens.md#integer-literals 32 | [FLOAT_LITERAL]: ../tokens.md#floating-point-literals 33 | [BOOLEAN_LITERAL]: ../tokens.md#boolean-literals 34 | -------------------------------------------------------------------------------- /src/expressions/method-call-expr.md: -------------------------------------------------------------------------------- 1 | # Method-call expressions 2 | 3 | > **Syntax**\ 4 | > _MethodCallExpression_ :\ 5 | >    [_Expression_] `.` [_PathExprSegment_] `(`[_CallParams_]? `)` 6 | 7 | A _method call_ consists of an expression (the *receiver*) followed by a single 8 | dot, an expression path segment, and a parenthesized expression-list. Method calls are 9 | resolved to associated [methods] on specific traits, either statically 10 | dispatching to a method if the exact `self`-type of the left-hand-side is known, 11 | or dynamically dispatching if the left-hand-side expression is an indirect 12 | [trait object](../types/trait-object.md). 13 | 14 | ```rust 15 | let pi: Result = "3.14".parse(); 16 | let log_pi = pi.unwrap_or(1.0).log(2.72); 17 | # assert!(1.14 < log_pi && log_pi < 1.15) 18 | ``` 19 | 20 | When looking up a method call, the receiver may be automatically dereferenced or 21 | borrowed in order to call a method. This requires a more complex lookup process 22 | than for other functions, since there may be a number of possible methods to 23 | call. The following procedure is used: 24 | 25 | The first step is to build a list of candidate receiver types. Obtain 26 | these by repeatedly [dereferencing][dereference] the receiver expression's type, 27 | adding each type encountered to the list, then finally attempting an [unsized 28 | coercion] at the end, and adding the result type if that is successful. Then, 29 | for each candidate `T`, add `&T` and `&mut T` to the list immediately after `T`. 30 | 31 | For instance, if the receiver has type `Box<[i32;2]>`, then the candidate types 32 | will be `Box<[i32;2]>`, `&Box<[i32;2]>`, `&mut Box<[i32;2]>`, `[i32; 2]` (by 33 | dereferencing), `&[i32; 2]`, `&mut [i32; 2]`, `[i32]` (by unsized coercion), 34 | `&[i32]`, and finally `&mut [i32]`. 35 | 36 | Then, for each candidate type `T`, search for a [visible] method with 37 | a receiver of that type in the following places: 38 | 39 | 1. `T`'s inherent methods (methods implemented directly on `T`). 40 | 1. Any of the methods provided by a [visible] trait implemented by `T`. If `T` 41 | is a type parameter, methods provided by trait bounds on `T` are looked up 42 | first. Then all remaining methods in scope are looked up. 43 | 44 | > Note: the lookup is done for each type in order, which can occasionally lead 45 | > to surprising results. The below code will print "In trait impl!", because 46 | > `&self` methods are looked up first, the trait method is found before the 47 | > struct's `&mut self` method is found. 48 | > 49 | > ```rust 50 | > struct Foo {} 51 | > 52 | > trait Bar { 53 | > fn bar(&self); 54 | > } 55 | > 56 | > impl Foo { 57 | > fn bar(&mut self) { 58 | > println!("In struct impl!") 59 | > } 60 | > } 61 | > 62 | > impl Bar for Foo { 63 | > fn bar(&self) { 64 | > println!("In trait impl!") 65 | > } 66 | > } 67 | > 68 | > fn main() { 69 | > let mut f = Foo{}; 70 | > f.bar(); 71 | > } 72 | > ``` 73 | 74 | If this results in multiple possible candidates, then it is an error, and the 75 | receiver must be [converted][disambiguate call] to an appropriate receiver type 76 | to make the method call. 77 | 78 | This process does not take into account the mutability or lifetime of the 79 | receiver, or whether a method is `unsafe`. Once a method is looked up, if it 80 | can't be called for one (or more) of those reasons, the result is a compiler 81 | error. 82 | 83 | If a step is reached where there is more than one possible method, such as where 84 | generic methods or traits are considered the same, then it is a compiler 85 | error. These cases require a [disambiguating function call syntax] for method 86 | and function invocation. 87 | 88 |
89 | 90 | ***Warning:*** For [trait objects], if there is an inherent method of the same 91 | name as a trait method, it will give a compiler error when trying to call the 92 | method in a method call expression. Instead, you can call the method using 93 | [disambiguating function call syntax], in which case it calls the trait 94 | method, not the inherent method. There is no way to call the inherent method. 95 | Just don't define inherent methods on trait objects with the same name a trait 96 | method and you'll be fine. 97 | 98 |
99 | 100 | [_CallParams_]: call-expr.md 101 | [_Expression_]: ../expressions.md 102 | [_PathExprSegment_]: ../paths.md#paths-in-expressions 103 | [visible]: ../visibility-and-privacy.md 104 | [trait objects]: ../types/trait-object.md 105 | [disambiguate call]: call-expr.md#disambiguating-function-calls 106 | [disambiguating function call syntax]: call-expr.md#disambiguating-function-calls 107 | [dereference]: operator-expr.md#the-dereference-operator 108 | [methods]: ../items/associated-items.md#methods 109 | [unsized coercion]: ../type-coercions.md#unsized-coercions 110 | -------------------------------------------------------------------------------- /src/expressions/path-expr.md: -------------------------------------------------------------------------------- 1 | # Path expressions 2 | 3 | > **Syntax**\ 4 | > _PathExpression_ :\ 5 | >       [_PathInExpression_]\ 6 | >    | [_QualifiedPathInExpression_] 7 | 8 | A [path] used as an expression context denotes either a local 9 | variable or an item. Path expressions that resolve to local or static variables 10 | are [place expressions], other paths are [value expressions]. Using a 11 | [`static mut`] variable requires an [`unsafe` block]. 12 | 13 | ```rust 14 | # mod globals { 15 | # pub static STATIC_VAR: i32 = 5; 16 | # pub static mut STATIC_MUT_VAR: i32 = 7; 17 | # } 18 | # let local_var = 3; 19 | local_var; 20 | globals::STATIC_VAR; 21 | unsafe { globals::STATIC_MUT_VAR }; 22 | let some_constructor = Some::; 23 | let push_integer = Vec::::push; 24 | let slice_reverse = <[i32]>::reverse; 25 | ``` 26 | 27 | [_PathInExpression_]: ../paths.md#paths-in-expressions 28 | [_QualifiedPathInExpression_]: ../paths.md#qualified-paths 29 | [place expressions]: ../expressions.md#place-expressions-and-value-expressions 30 | [value expressions]: ../expressions.md#place-expressions-and-value-expressions 31 | [path]: ../paths.md 32 | [`static mut`]: ../items/static-items.md#mutable-statics 33 | [`unsafe` block]: block-expr.md#unsafe-blocks 34 | -------------------------------------------------------------------------------- /src/expressions/range-expr.md: -------------------------------------------------------------------------------- 1 | # Range expressions 2 | 3 | > **Syntax**\ 4 | > _RangeExpression_ :\ 5 | >       _RangeExpr_\ 6 | >    | _RangeFromExpr_\ 7 | >    | _RangeToExpr_\ 8 | >    | _RangeFullExpr_\ 9 | >    | _RangeInclusiveExpr_\ 10 | >    | _RangeToInclusiveExpr_ 11 | > 12 | > _RangeExpr_ :\ 13 | >    [_Expression_] `..` [_Expression_] 14 | > 15 | > _RangeFromExpr_ :\ 16 | >    [_Expression_] `..` 17 | > 18 | > _RangeToExpr_ :\ 19 | >    `..` [_Expression_] 20 | > 21 | > _RangeFullExpr_ :\ 22 | >    `..` 23 | > 24 | > _RangeInclusiveExpr_ :\ 25 | >    [_Expression_] `..=` [_Expression_] 26 | > 27 | > _RangeToInclusiveExpr_ :\ 28 | >    `..=` [_Expression_] 29 | 30 | The `..` and `..=` operators will construct an object of one of the 31 | `std::ops::Range` (or `core::ops::Range`) variants, according to the following 32 | table: 33 | 34 | | Production | Syntax | Type | Range | 35 | |------------------------|---------------|------------------------------|-----------------------| 36 | | _RangeExpr_ | start`..`end | [std::ops::Range] | start ≤ x < end | 37 | | _RangeFromExpr_ | start`..` | [std::ops::RangeFrom] | start ≤ x | 38 | | _RangeToExpr_ | `..`end | [std::ops::RangeTo] | x < end | 39 | | _RangeFullExpr_ | `..` | [std::ops::RangeFull] | - | 40 | | _RangeInclusiveExpr_ | start`..=`end | [std::ops::RangeInclusive] | start ≤ x ≤ end | 41 | | _RangeToInclusiveExpr_ | `..=`end | [std::ops::RangeToInclusive] | x ≤ end | 42 | 43 | Examples: 44 | 45 | ```rust 46 | 1..2; // std::ops::Range 47 | 3..; // std::ops::RangeFrom 48 | ..4; // std::ops::RangeTo 49 | ..; // std::ops::RangeFull 50 | 5..=6; // std::ops::RangeInclusive 51 | ..=7; // std::ops::RangeToInclusive 52 | ``` 53 | 54 | The following expressions are equivalent. 55 | 56 | ```rust 57 | let x = std::ops::Range {start: 0, end: 10}; 58 | let y = 0..10; 59 | 60 | assert_eq!(x, y); 61 | ``` 62 | 63 | Ranges can be used in `for` loops: 64 | 65 | ```rust 66 | for i in 1..11 { 67 | println!("{}", i); 68 | } 69 | ``` 70 | 71 | [_Expression_]: ../expressions.md 72 | 73 | [std::ops::Range]: https://doc.rust-lang.org/std/ops/struct.Range.html 74 | [std::ops::RangeFrom]: https://doc.rust-lang.org/std/ops/struct.RangeFrom.html 75 | [std::ops::RangeTo]: https://doc.rust-lang.org/std/ops/struct.RangeTo.html 76 | [std::ops::RangeFull]: https://doc.rust-lang.org/std/ops/struct.RangeFull.html 77 | [std::ops::RangeInclusive]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html 78 | [std::ops::RangeToInclusive]: https://doc.rust-lang.org/std/ops/struct.RangeToInclusive.html 79 | -------------------------------------------------------------------------------- /src/expressions/return-expr.md: -------------------------------------------------------------------------------- 1 | # `return` expressions 2 | 3 | > **Syntax**\ 4 | > _ReturnExpression_ :\ 5 | >    `return` [_Expression_]? 6 | 7 | Return expressions are denoted with the keyword `return`. Evaluating a `return` 8 | expression moves its argument into the designated output location for the 9 | current function call, destroys the current function activation frame, and 10 | transfers control to the caller frame. 11 | 12 | An example of a `return` expression: 13 | 14 | ```rust 15 | fn max(a: i32, b: i32) -> i32 { 16 | if a > b { 17 | return a; 18 | } 19 | return b; 20 | } 21 | ``` 22 | 23 | [_Expression_]: ../expressions.md 24 | -------------------------------------------------------------------------------- /src/expressions/struct-expr.md: -------------------------------------------------------------------------------- 1 | # Struct expressions 2 | 3 | > **Syntax**\ 4 | > _StructExpression_ :\ 5 | >       _StructExprStruct_\ 6 | >    | _StructExprTuple_\ 7 | >    | _StructExprUnit_ 8 | > 9 | > _StructExprStruct_ :\ 10 | >    [_PathInExpression_] `{` [_InnerAttribute_]\* (_StructExprFields_ | _StructBase_)? `}` 11 | > 12 | > _StructExprFields_ :\ 13 | >    _StructExprField_ (`,` _StructExprField_)\* (`,` _StructBase_ | `,`?) 14 | > 15 | > _StructExprField_ :\ 16 | >       [IDENTIFIER]\ 17 | >    | ([IDENTIFIER] | [TUPLE_INDEX]) `:` [_Expression_] 18 | > 19 | > _StructBase_ :\ 20 | >    `..` [_Expression_] 21 | > 22 | > _StructExprTuple_ :\ 23 | >    [_PathInExpression_] `(`\ 24 | >       [_InnerAttribute_]\*\ 25 | >       ( [_Expression_] (`,` [_Expression_])\* `,`? )?\ 26 | >    `)` 27 | > 28 | > _StructExprUnit_ : [_PathInExpression_] 29 | 30 | A _struct expression_ creates a struct or union value. It consists of a path to a [struct] 31 | or [union] item followed by the values for the fields of the item. There are three forms 32 | of struct expressions: struct, tuple, and unit. 33 | 34 | The following are examples of struct expressions: 35 | 36 | ```rust 37 | # struct Point { x: f64, y: f64 } 38 | # struct NothingInMe { } 39 | # struct TuplePoint(f64, f64); 40 | # mod game { pub struct User<'a> { pub name: &'a str, pub age: u32, pub score: usize } } 41 | # struct Cookie; fn some_fn(t: T) {} 42 | Point {x: 10.0, y: 20.0}; 43 | NothingInMe {}; 44 | TuplePoint(10.0, 20.0); 45 | TuplePoint { 0: 10.0, 1: 20.0 }; // Results in the same value as the above line 46 | let u = game::User {name: "Joe", age: 35, score: 100_000}; 47 | some_fn::(Cookie); 48 | ``` 49 | 50 | ## Field struct expression 51 | 52 | A struct expression with fields enclosed in curly braces allows you to specify the value 53 | for each individual field in any order. The field name is separated from its value with a 54 | colon. 55 | 56 | A value of a [union] type can also be created using this syntax, except that it must 57 | specify exactly one field. 58 | 59 | ## Functional update syntax 60 | 61 | A struct expression can terminate with the syntax `..` followed by an 62 | expression to denote a functional update. The expression following `..` (the 63 | base) must have the same struct type as the new struct type being formed. 64 | 65 | The entire expression uses the given values for the fields that were specified 66 | and moves or copies the remaining fields from the base expression. As with all 67 | struct expressions, all of the fields of the struct must be [visible], even 68 | those not explicitly named. 69 | 70 | ```rust 71 | # struct Point3d { x: i32, y: i32, z: i32 } 72 | let mut base = Point3d {x: 1, y: 2, z: 3}; 73 | let y_ref = &mut base.y; 74 | Point3d {y: 0, z: 10, .. base}; // OK, only base.x is accessed 75 | drop(y_ref); 76 | ``` 77 | 78 | Struct expressions with curly braces can't be used directly in a [loop] or [if] 79 | expression's head, or in the [scrutinee] of an [if let] or [match] expression. 80 | However, struct expressions can be in used in these situations if they are 81 | within another expression, for example inside [parentheses]. 82 | 83 | The field names can be decimal integer values to specify indices for constructing tuple 84 | structs. This can be used with base structs to fill out the remaining indices not 85 | specified: 86 | 87 | ```rust 88 | struct Color(u8, u8, u8); 89 | let c1 = Color(0, 0, 0); // Typical way of creating a tuple struct. 90 | let c2 = Color{0: 255, 1: 127, 2: 0}; // Specifying fields by index. 91 | let c3 = Color{1: 0, ..c2}; // Fill out all other fields using a base struct. 92 | ``` 93 | 94 | ### Struct field init shorthand 95 | 96 | When initializing a data structure (struct, enum, union) with named (but not 97 | numbered) fields, it is allowed to write `fieldname` as a shorthand for 98 | `fieldname: fieldname`. This allows a compact syntax with less duplication. 99 | For example: 100 | 101 | ```rust 102 | # struct Point3d { x: i32, y: i32, z: i32 } 103 | # let x = 0; 104 | # let y_value = 0; 105 | # let z = 0; 106 | Point3d { x: x, y: y_value, z: z }; 107 | Point3d { x, y: y_value, z }; 108 | ``` 109 | 110 | ## Tuple struct expression 111 | 112 | A struct expression with fields enclosed in parentheses constructs a tuple struct. Though 113 | it is listed here as a specific expression for completeness, it is equivalent to a [call 114 | expression] to the tuple struct's constructor. For example: 115 | 116 | ```rust 117 | struct Position(i32, i32, i32); 118 | Position(0, 0, 0); // Typical way of creating a tuple struct. 119 | let c = Position; // `c` is a function that takes 3 arguments. 120 | let pos = c(8, 6, 7); // Creates a `Position` value. 121 | ``` 122 | 123 | ## Unit struct expression 124 | 125 | A unit struct expression is just the path to a unit struct item. This refers to the unit 126 | struct's implicit constant of its value. The unit struct value can also be constructed 127 | with a fieldless struct expression. For example: 128 | 129 | ```rust 130 | struct Gamma; 131 | let a = Gamma; // Gamma unit value. 132 | let b = Gamma{}; // Exact same value as `a`. 133 | ``` 134 | 135 | ## Struct expression attributes 136 | 137 | [Inner attributes] are allowed directly after the opening brace or parenthesis 138 | of a struct expression in the same expression contexts as [attributes on block 139 | expressions]. 140 | 141 | [IDENTIFIER]: ../identifiers.md 142 | [Inner attributes]: ../attributes.md 143 | [TUPLE_INDEX]: ../tokens.md#integer-literals 144 | [_Expression_]: ../expressions.md 145 | [_InnerAttribute_]: ../attributes.md 146 | [_PathInExpression_]: ../paths.md#paths-in-expressions 147 | [attributes on block expressions]: block-expr.md#attributes-on-block-expressions 148 | [call expression]: call-expr.md 149 | [if let]: if-expr.md#if-let-expressions 150 | [if]: if-expr.md#if-expressions 151 | [loop]: loop-expr.md 152 | [match]: match-expr.md 153 | [parentheses]: grouped-expr.md 154 | [struct]: ../items/structs.md 155 | [union]: ../items/unions.md 156 | [visible]: ../visibility-and-privacy.md 157 | [scrutinee]: ../glossary.md#scrutinee 158 | -------------------------------------------------------------------------------- /src/expressions/tuple-expr.md: -------------------------------------------------------------------------------- 1 | # Tuple and tuple indexing expressions 2 | 3 | ## Tuple expressions 4 | 5 | > **Syntax**\ 6 | > _TupleExpression_ :\ 7 | >    `(` [_InnerAttribute_]\* _TupleElements_? `)` 8 | > 9 | > _TupleElements_ :\ 10 | >    ( [_Expression_] `,` )+ [_Expression_]? 11 | 12 | Tuples are written by enclosing zero or more comma-separated expressions in 13 | parentheses. They are used to create [tuple-typed](../types/tuple.md) 14 | values. 15 | 16 | ```rust 17 | (0.0, 4.5); 18 | ("a", 4usize, true); 19 | (); 20 | ``` 21 | 22 | You can disambiguate a single-element tuple from a value in parentheses with a 23 | comma: 24 | 25 | ```rust 26 | (0,); // single-element tuple 27 | (0); // zero in parentheses 28 | ``` 29 | 30 | ### Tuple expression attributes 31 | 32 | [Inner attributes] are allowed directly after the opening parenthesis of a 33 | tuple expression in the same expression contexts as [attributes on block 34 | expressions]. 35 | 36 | ## Tuple indexing expressions 37 | 38 | > **Syntax**\ 39 | > _TupleIndexingExpression_ :\ 40 | >    [_Expression_] `.` [TUPLE_INDEX] 41 | 42 | [Tuples](../types/tuple.md) and [struct tuples](../items/structs.md) can be 43 | indexed using the number corresponding to the position of the field. The index 44 | must be written as a [decimal literal](../tokens.md#integer-literals) with no 45 | underscores or suffix. Tuple indexing expressions also differ from field 46 | expressions in that they can unambiguously be called as a function. In all 47 | other aspects they have the same behavior. 48 | 49 | ```rust 50 | # struct Point(f32, f32); 51 | let pair = (1, 2); 52 | assert_eq!(pair.1, 2); 53 | let unit_x = Point(1.0, 0.0); 54 | assert_eq!(unit_x.0, 1.0); 55 | ``` 56 | 57 | [Inner attributes]: ../attributes.md 58 | [TUPLE_INDEX]: ../tokens.md#integer-literals 59 | [_Expression_]: ../expressions.md 60 | [_InnerAttribute_]: ../attributes.md 61 | [attributes on block expressions]: block-expr.md#attributes-on-block-expressions 62 | -------------------------------------------------------------------------------- /src/identifiers.md: -------------------------------------------------------------------------------- 1 | # 标识符 2 | 3 | > [identifiers.md](https://github.com/rust-lang/reference/blob/master/src/identifiers.md) 4 | >
5 | > commit 34d27fe8bc8b89b55da690484d1e17fbd0f25055 6 | 7 | > **Lexer:**\ 8 | > 标识符_或_关键字:\ 9 | >       [`a`-`z` `A`-`Z`] [`a`-`z` `A`-`Z` `0`-`9` `_`]\*\ 10 | >    | `_` [`a`-`z` `A`-`Z` `0`-`9` `_`]+ 11 | > 12 | > RAW_IDENTIFIER 译否? : `r#` IDENTIFIER_OR_KEYWORD 译否? *除外:`crate`, `self`, `super`, `Self`* 13 | > 14 | > NON_KEYWORD_IDENTIFIER 译否? : IDENTIFIER_OR_KEYWORD 译否? *除外:[规定关键字]或[保留关键字]* 15 | > 16 | > IDENTIFIER 译否? :\ 17 | > NON_KEYWORD_IDENTIFIER 译否? | RAW_IDENTIFIER 译否? 18 | 19 | 标识符是如下形式的任何非空 ASCII 字符串: 20 | 21 | 要么是—— 22 | 23 | * 首字符是字母。 24 | * 其余字符是字母、数字,或 `_`。 25 | 26 | 要么是—— 27 | 28 | * 首字符是 `_`。 29 | * 标识符由多个字符组成,单个 `_` 不是有效标识符。 30 | * 其余字符是字母、数字,或 `_`。 31 | 32 | 原生标识符类似于普通标识符,但前缀是 `r#`(注意 `r#` 不包括在实际标识符中)。原生标识符与普通标识符的区别是:原生标识符可以是除上述列举的 `RAW_IDENTIFIER` 外的任何规定关键字或保留关键字。 33 | 34 | [规定关键字]: keywords.md#strict-keywords 35 | [保留关键字]: keywords.md#reserved-keywords 36 | -------------------------------------------------------------------------------- /src/imgs/contributors/anonymous.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzy/rust-reference-zh-cn/02d06fa67b9760580e11f27baa7edf054a264d04/src/imgs/contributors/anonymous.jpg -------------------------------------------------------------------------------- /src/imgs/contributors/zzy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzy/rust-reference-zh-cn/02d06fa67b9760580e11f27baa7edf054a264d04/src/imgs/contributors/zzy.jpg -------------------------------------------------------------------------------- /src/influences.md: -------------------------------------------------------------------------------- 1 | # Influences 2 | 3 | Rust is not a particularly original language, with design elements coming from 4 | a wide range of sources. Some of these are listed below (including elements 5 | that have since been removed): 6 | 7 | * SML, OCaml: algebraic data types, pattern matching, type inference, 8 | semicolon statement separation 9 | * C++: references, RAII, smart pointers, move semantics, monomorphization, 10 | memory model 11 | * ML Kit, Cyclone: region based memory management 12 | * Haskell (GHC): typeclasses, type families 13 | * Newsqueak, Alef, Limbo: channels, concurrency 14 | * Erlang: message passing, thread failure, linked thread failure, 15 | lightweight concurrency 16 | * Swift: optional bindings 17 | * Scheme: hygienic macros 18 | * C#: attributes 19 | * Ruby: closure syntax, block syntax 20 | * NIL, Hermes: typestate 21 | * [Unicode Annex #31](http://www.unicode.org/reports/tr31/): identifier and 22 | pattern syntax 23 | -------------------------------------------------------------------------------- /src/input-format.md: -------------------------------------------------------------------------------- 1 | # 输入格式 2 | 3 | > [input-format.md](https://github.com/rust-lang/reference/blob/master/src/input-format.md) 4 | >
5 | > commit a2405b970b7c8222a483b82213adcb17d646c75d 6 | 7 | Rust 的输入被诠释为用 UTF-8 编码的 Unicode 码序列。 8 | -------------------------------------------------------------------------------- /src/interior-mutability.md: -------------------------------------------------------------------------------- 1 | # Interior Mutability 2 | 3 | Sometimes a type needs to be mutated while having multiple aliases. In Rust this 4 | is achieved using a pattern called _interior mutability_. A type has interior 5 | mutability if its internal state can be changed through a [shared reference] to 6 | it. This goes against the usual [requirement][ub] that the value pointed to by a 7 | shared reference is not mutated. 8 | 9 | [`std::cell::UnsafeCell`] type is the only allowed way in Rust to disable 10 | this requirement. When `UnsafeCell` is immutably aliased, it is still safe to 11 | mutate, or obtain a mutable reference to, the `T` it contains. As with all 12 | other types, it is undefined behavior to have multiple `&mut UnsafeCell` 13 | aliases. 14 | 15 | Other types with interior mutability can be created by using `UnsafeCell` as 16 | a field. The standard library provides a variety of types that provide safe 17 | interior mutability APIs. For example, [`std::cell::RefCell`] uses run-time 18 | borrow checks to ensure the usual rules around multiple references. The 19 | [`std::sync::atomic`] module contains types that wrap a value that is only 20 | accessed with atomic operations, allowing the value to be shared and mutated 21 | across threads. 22 | 23 | [shared reference]: types/pointer.md#shared-references- 24 | [ub]: behavior-considered-undefined.md 25 | [`std::cell::UnsafeCell`]: ../std/cell/struct.UnsafeCell.html 26 | [`std::cell::RefCell`]: ../std/cell/struct.RefCell.html 27 | [`std::sync::atomic`]: ../std/sync/atomic/index.html 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/introduction.md: -------------------------------------------------------------------------------- 1 | # 介绍 2 | 3 | > 💥 暂翻译至[模块](https://rust-reference.budshome.com/items/modules.html)一节。
4 | > 欢迎您,一起参与。 5 | # 暂忙于[《Rust 生态实践指南》](http://rust-crate-guide.budshome.com),本书暂停。 6 | 7 | > [introduction.md](https://github.com/rust-lang/reference/blob/master/src/introduction.md) 8 | >
9 | > commit 1995d18b04a59368f4a91c600876ad987521d833 10 | 11 | 本书是 Rust 编程语言的主要参考,提供了3类资料: 12 | 13 | - 一些章节非正式地介绍了每种语言结构及其用法。 14 | - 一些章节非正式地介绍了内存模型、并发模型、运行时服务、链接模型,以及调试工具。 15 | - 附录章节提供了影响设计的 Rust 语言基础原理和其参考资料。 16 | 17 |
18 | 19 | 警告:此书暂未完成,每篇参考的记录都需花一些时间。有关本书未记录的内容,请查阅 [GitHub issues]。 20 | 21 |
22 | 23 | ## *参考手册* 并非—— 24 | 25 | 本书并非 Rust 语言入门,阅读它需要有一定的 Rust 语言基础。若你需要学习语言基础,请阅读 [Rust 程序设计语言]。 26 | 27 | 本书也非 Rust 语言发行版所包含的[标准库]的参考资料,[标准库]文档来源于从源码中抽取的文档属性。许多你期待是 Rust 语言特性的部分,可能属于 [Rust 标准库][标准库]特性。所以你应该在库文档中查阅,而非此书。 28 | 29 | 类似地,本书通常不能作为记录 `rustc` 或者 `Cargo` 细节的工具书。`rustc` 有自己的[书籍][rustc book],`Cargo` 有一本包含[参考资料][cargo reference]的[书籍][cargo book]。本书中,包含一些诸如[链接][linkage]的章节,介绍了 `rustc` 是如何工作的。 30 | 31 | 本书也仅作为 Rust 稳定版的参考资料,关于尚在完善的非稳定特性,请阅读[非稳定版书籍][Unstable Book]。 32 | 33 | 最后一点,本书并非标准。其包含的一些细节是 `rustc` 自身规范,不应作为 Rust 语言规范。我们计划以后写一本关于 Rust 语言规范的书籍,但目前,此参考手册是最接近 Rust 语言规范的资料。 34 | 35 | ## 如何使用此书 36 | 37 | 本书无需按章节顺序阅读。每章节都可以独立阅读,但会交叉连接到其他章节,以了解所提到的 Rust 语言的各方面内容——但不详述。 38 | 39 | 阅读本书有两种主要方式。 40 | 41 | 第一,寻找特定问题的答案。如果你知道回答问题的章节,你可以直接从目录跳入章节进行阅读。否则,你可以按 `s` 键或单击顶部栏上的放大镜来搜索与问题相关的关键字(译者注:暂不能搜索非英文)。例如:假设你想知道 `let` 语句创建的临时值什么时候会被删除;同时,假设你还不知道[表达式][expressions chapter]一章中定义了[临时对象的生命周期][lifetime of temporaries]。那么,你可以搜索 `temporary let`,第一个搜索结果将带你阅读该部分。 42 | 43 | 第二,概括地提高你对 Rust 语言某一方面的认知。这种情况下,只要你浏览目录时看到了想了解的内容,就去开始阅读。如果某个链接看起来挺有趣,点击并阅读该部分。 44 | 45 | 综上所述,本书没有错误的阅读方式,按照你感觉最有帮助的方式去读它吧。 46 | 47 | ### 约定 48 | 49 | 像所有技术书籍一样,在信息的展示方面,本书有一些约定。 50 | 51 | * 定义术语的语句中,术语写为*斜体*。当术语在其定义章节之外使用时,通常会有一个链接指向术语定义的片段。 52 | 53 | *示例术语*是一个定义术语的示例。 54 | 55 | * 编译 crate 的 Rust 语言版本的差异,以**版本差异**开始,记录在块引用中。 56 | 57 | > **版本差异**:此语法 2015 版本有效,2018 版本起不允许使用。 58 | 59 | * 有关书籍状态的,或者大部分超出本书范围的有用资料,以**注**开始,记录在块引用中。 60 | 61 | > **注**:这是一个注释示例。 62 | 63 | * 有关对语言的不健全行为,或者易于混淆的语言特性的警告,记录在特殊的警告框里。 64 | 65 |
66 | 67 | 警告:示例警告。 68 | 69 |
70 | 71 | * 代码片段内联在 `` 标签里。 72 | 73 | 较长的示例代码放在语法高亮的代码框内,其右上角有用于复制、运行和显示隐藏行的控件。 74 | 75 | ```rust 76 | # // 这是隐藏行 77 | fn main() { 78 | println!("这是示例代码"); 79 | } 80 | ``` 81 | 82 | * 语法和词法结构,放在块引用中,第一行为粗体上标 **Lexer****Syntax**。 83 | 84 | > **Syntax**\ 85 | > _语法示例_:\ 86 | >       `~` [ _表达式_ ]\ 87 | >    | `box` [ _表达式_ ] 88 | 89 | 查阅[标记法][Notation]以获取更多细节。 90 | 91 | ## 贡献者 ✨ 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 |

Zhang Zhongyu

欢迎您

欢迎您

欢迎您

欢迎您

欢迎您
103 | 104 | ## 做贡献 105 | 106 | 我们欢迎各类贡献。 107 | 108 | 欢迎 fork[《Rust 参考手册》中文翻译仓库],欢迎提交问题,欢迎发送 PR。 109 | 110 | [Rust 程序设计语言]: https://rust-lang.budshome.com 111 | [github issues]: https://github.com/rust-lang/reference/issues 112 | [标准库]: https://doc.rust-lang.org/std 113 | [《Rust 参考手册》中文翻译仓库]: https://github.com/zzy/rust-reference-zh-cn 114 | [Unstable Book]: https://doc.rust-lang.org/nightly/unstable-book/ 115 | [_Expression_]: expressions.md 116 | [cargo book]: https://cargo.budshome.com 117 | [cargo reference]: https://cargo.budshome.com/reference 118 | [expressions chapter]: expressions.md 119 | [lifetime of temporaries]: expressions.md#temporary-lifetimes 120 | [linkage]: linkage.md 121 | [rustc book]: https://doc.rust-lang.org/nightly/rustc/index.html 122 | [Notation]: notation.md 123 | -------------------------------------------------------------------------------- /src/items.md: -------------------------------------------------------------------------------- 1 | # 项 2 | 3 | > [items.md](https://github.com/rust-lang/reference/blob/master/src/items.md) 4 | >
5 | > commit - b0e0ad6490d6517c19546b1023948986578fc378 - 2019-07-16 6 | 7 | > **Syntax:**\ 8 | > _Item_:\ 9 | >    [_OuterAttribute_]\*\ 10 | >       _VisItem_\ 11 | >    | _MacroItem_ 12 | > 13 | > _VisItem_:\ 14 | >    [_Visibility_]?\ 15 | >    (\ 16 | >          [_Module_]\ 17 | >       | [_ExternCrate_]\ 18 | >       | [_UseDeclaration_]\ 19 | >       | [_Function_]\ 20 | >       | [_TypeAlias_]\ 21 | >       | [_Struct_]\ 22 | >       | [_Enumeration_]\ 23 | >       | [_Union_]\ 24 | >       | [_ConstantItem_]\ 25 | >       | [_StaticItem_]\ 26 | >       | [_Trait_]\ 27 | >       | [_Implementation_]\ 28 | >       | [_ExternBlock_]\ 29 | >    )` 30 | > 31 | > _MacroItem_:\ 32 | >       [_MacroInvocationSemi_]\ 33 | >    | [_MacroRulesDefinition_] 34 | 35 | _项(item)_ 是 crate 的一个组件。项在 crate 中被组织为一个嵌套的[模块][modules]集。每个 crate 都有一个单独的“最外层”的匿名模块;crate 中的所有其它项,在 crate 中的模块树中都有路径。 36 | 37 | 项全部在编译时被确定,大部分在执行期间保持不变,并可能驻留在只读内存中。 38 | 39 | 项有以下几种类型: 40 | 41 | * [模块][modules] 42 | * [extern crate 声明][`extern crate` declarations] 43 | * [use 声明][`use` declarations] 44 | * [函数定义][function definitions] 45 | * [类型定义][type definitions] 46 | * [结构体定义][struct definitions] 47 | * [枚举定义][enumeration definitions] 48 | * [联合体定义][union definitions] 49 | * [常量项][constant items] 50 | * [静态项][static items] 51 | * [trait 定义][trait definitions] 52 | * [实现][implementations] 53 | * [`外部`块][`extern` blocks] 54 | 55 | 这些范围内的项与定义在作用域外声明的项是一样的--它仍是一个静态项--除了那些位于模块命名空间中的路径名称由包含其中的项的名字定义的项,或者是其包含的私有项(对于函数来说)。 56 | 57 | 有些项组成了子项声明的隐式作用域。换句话说,在一个函数或模块中,项的声明可以(在许多情况下)与语句、控制块和类似的构件混合在一起,否则这些构件将构成项体。这些作用域内的项的含义与在作用域外声明的项的含义相同——它仍然是静态项——只是模块命名空间中的项的 *路径名* 由包含该项的封闭项名称限定,或者是包含该项的封闭项的私有项(对于函数来说)。由语法指定子项声明可能出现的确切位置。 58 | 59 | [_ConstantItem_]: items/constant-items.md 60 | [_Enumeration_]: items/enumerations.md 61 | [_ExternBlock_]: items/external-blocks.md 62 | [_ExternCrate_]: items/extern-crates.md 63 | [_Function_]: items/functions.md 64 | [_Implementation_]: items/implementations.md 65 | [_MacroInvocationSemi_]: macros.md#macro-invocation 66 | [_MacroRulesDefinition_]: macros-by-example.md 67 | [_Module_]: items/modules.md 68 | [_OuterAttribute_]: attributes.md 69 | [_StaticItem_]: items/static-items.md 70 | [_Struct_]: items/structs.md 71 | [_Trait_]: items/traits.md 72 | [_TypeAlias_]: items/type-aliases.md 73 | [_Union_]: items/unions.md 74 | [_UseDeclaration_]: items/use-declarations.md 75 | [_Visibility_]: visibility-and-privacy.md 76 | [`extern crate` declarations]: items/extern-crates.md 77 | [`extern` blocks]: items/external-blocks.md 78 | [`use` declarations]: items/use-declarations.md 79 | [constant items]: items/constant-items.md 80 | [enumeration definitions]: items/enumerations.md 81 | [function definitions]: items/functions.md 82 | [implementations]: items/implementations.md 83 | [modules]: items/modules.md 84 | [paths]: paths.md 85 | [static items]: items/static-items.md 86 | [struct definitions]: items/structs.md 87 | [trait definitions]: items/traits.md 88 | [type definitions]: items/type-aliases.md 89 | [union definitions]: items/unions.md 90 | -------------------------------------------------------------------------------- /src/items/constant-items.md: -------------------------------------------------------------------------------- 1 | # Constant items 2 | 3 | > **Syntax**\ 4 | > _ConstantItem_ :\ 5 | >    `const` ( [IDENTIFIER] | `_` ) `:` [_Type_] `=` [_Expression_] `;` 6 | 7 | A *constant item* is an optionally named _[constant value]_ which is not associated 8 | with a specific memory location in the program. Constants are essentially inlined 9 | wherever they are used, meaning that they are copied directly into the relevant 10 | context when used. References to the same constant are not necessarily 11 | guaranteed to refer to the same memory address. 12 | 13 | Constants must be explicitly typed. The type must have a `'static` lifetime: any 14 | references it contains must have `'static` lifetimes. 15 | 16 | Constants may refer to the address of other constants, in which case the 17 | address will have elided lifetimes where applicable, otherwise – in most cases 18 | – defaulting to the `static` lifetime. (See [static lifetime 19 | elision].) The compiler is, however, still at liberty to translate the constant 20 | many times, so the address referred to may not be stable. 21 | 22 | ```rust 23 | const BIT1: u32 = 1 << 0; 24 | const BIT2: u32 = 1 << 1; 25 | 26 | const BITS: [u32; 2] = [BIT1, BIT2]; 27 | const STRING: &'static str = "bitstring"; 28 | 29 | struct BitsNStrings<'a> { 30 | mybits: [u32; 2], 31 | mystring: &'a str, 32 | } 33 | 34 | const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings { 35 | mybits: BITS, 36 | mystring: STRING, 37 | }; 38 | ``` 39 | 40 | ## Constants with Destructors 41 | 42 | Constants can contain destructors. Destructors are run when the value goes out 43 | of scope. 44 | 45 | ```rust 46 | struct TypeWithDestructor(i32); 47 | 48 | impl Drop for TypeWithDestructor { 49 | fn drop(&mut self) { 50 | println!("Dropped. Held {}.", self.0); 51 | } 52 | } 53 | 54 | const ZERO_WITH_DESTRUCTOR: TypeWithDestructor = TypeWithDestructor(0); 55 | 56 | fn create_and_drop_zero_with_destructor() { 57 | let x = ZERO_WITH_DESTRUCTOR; 58 | // x gets dropped at end of function, calling drop. 59 | // prints "Dropped. Held 0.". 60 | } 61 | ``` 62 | 63 | ## Unnamed constant 64 | 65 | Unlike an [associated] constant, a [free] constant may be unnamed by using 66 | an underscore instead of the name. For example: 67 | 68 | ```rust 69 | const _: () = { struct _SameNameTwice; }; 70 | 71 | // OK although it is the same name as above: 72 | const _: () = { struct _SameNameTwice; }; 73 | ``` 74 | 75 | As with [underscore imports], macros may safely emit the same unnamed constant in 76 | the same scope more than once. For example, the following should not produce an error: 77 | 78 | ```rust 79 | macro_rules! m { 80 | ($item: item) => { $item $item } 81 | } 82 | 83 | m!(const _: () = ();); 84 | // This expands to: 85 | // const _: () = (); 86 | // const _: () = (); 87 | ``` 88 | 89 | [associated]: ../glossary.md#associated-item 90 | [constant value]: ../const_eval.md#constant-expressions 91 | [free]: ../glossary.md#free-item 92 | [static lifetime elision]: ../lifetime-elision.md#static-lifetime-elision 93 | [IDENTIFIER]: ../identifiers.md 94 | [underscore imports]: use-declarations.md#underscore-imports 95 | [_Type_]: ../types.md#type-expressions 96 | [_Expression_]: ../expressions.md 97 | -------------------------------------------------------------------------------- /src/items/enumerations.md: -------------------------------------------------------------------------------- 1 | # Enumerations 2 | 3 | > **Syntax**\ 4 | > _Enumeration_ :\ 5 | >    `enum` 6 | > [IDENTIFIER]  7 | > [_Generics_]? 8 | > [_WhereClause_]? 9 | > `{` _EnumItems_? `}` 10 | > 11 | > _EnumItems_ :\ 12 | >    _EnumItem_ ( `,` _EnumItem_ )\* `,`? 13 | > 14 | > _EnumItem_ :\ 15 | >    _OuterAttribute_\* [_Visibility_]?\ 16 | >    [IDENTIFIER] ( _EnumItemTuple_ | _EnumItemStruct_ 17 | > | _EnumItemDiscriminant_ )? 18 | > 19 | > _EnumItemTuple_ :\ 20 | >    `(` [_TupleFields_]? `)` 21 | > 22 | > _EnumItemStruct_ :\ 23 | >    `{` [_StructFields_]? `}` 24 | > 25 | > _EnumItemDiscriminant_ :\ 26 | >    `=` [_Expression_] 27 | 28 | An *enumeration*, also referred to as *enum* is a simultaneous definition of a 29 | nominal [enumerated type] as well as a set of *constructors*, that can be used 30 | to create or pattern-match values of the corresponding enumerated type. 31 | 32 | Enumerations are declared with the keyword `enum`. 33 | 34 | An example of an `enum` item and its use: 35 | 36 | ```rust 37 | enum Animal { 38 | Dog, 39 | Cat, 40 | } 41 | 42 | let mut a: Animal = Animal::Dog; 43 | a = Animal::Cat; 44 | ``` 45 | 46 | Enum constructors can have either named or unnamed fields: 47 | 48 | ```rust 49 | enum Animal { 50 | Dog(String, f64), 51 | Cat { name: String, weight: f64 }, 52 | } 53 | 54 | let mut a: Animal = Animal::Dog("Cocoa".to_string(), 37.2); 55 | a = Animal::Cat { name: "Spotty".to_string(), weight: 2.7 }; 56 | ``` 57 | 58 | In this example, `Cat` is a _struct-like enum variant_, whereas `Dog` is simply 59 | called an enum variant. Each enum instance has a _discriminant_ which is an 60 | integer associated to it that is used to determine which variant it holds. An 61 | opaque reference to this discriminant can be obtained with the 62 | [`mem::discriminant`] function. 63 | 64 | ## Custom Discriminant Values for Fieldless Enumerations 65 | 66 | If there is no data attached to *any* of the variants of an enumeration, 67 | then the discriminant can be directly chosen and accessed. 68 | 69 | These enumerations can be cast to integer types with the `as` operator by a 70 | [numeric cast]. The enumeration can optionally specify which integer each 71 | discriminant gets by following the variant name with `=` followed by a [constant 72 | expression]. If the first variant in the declaration is unspecified, then it is 73 | set to zero. For every other unspecified discriminant, it is set to one higher 74 | than the previous variant in the declaration. 75 | 76 | ```rust 77 | enum Foo { 78 | Bar, // 0 79 | Baz = 123, // 123 80 | Quux, // 124 81 | } 82 | 83 | let baz_discriminant = Foo::Baz as u32; 84 | assert_eq!(baz_discriminant, 123); 85 | ``` 86 | 87 | Under the [default representation], the specified discriminant is interpreted as 88 | an `isize` value although the compiler is allowed to use a smaller type in the 89 | actual memory layout. The size and thus acceptable values can be changed by 90 | using a [primitive representation] or the [`C` representation]. 91 | 92 | It is an error when two variants share the same discriminant. 93 | 94 | ```rust,compile_fail 95 | enum SharedDiscriminantError { 96 | SharedA = 1, 97 | SharedB = 1 98 | } 99 | 100 | enum SharedDiscriminantError2 { 101 | Zero, // 0 102 | One, // 1 103 | OneToo = 1 // 1 (collision with previous!) 104 | } 105 | ``` 106 | 107 | It is also an error to have an unspecified discriminant where the previous 108 | discriminant is the maximum value for the size of the discriminant. 109 | 110 | ```rust,compile_fail 111 | #[repr(u8)] 112 | enum OverflowingDiscriminantError { 113 | Max = 255, 114 | MaxPlusOne // Would be 256, but that overflows the enum. 115 | } 116 | 117 | #[repr(u8)] 118 | enum OverflowingDiscriminantError2 { 119 | MaxMinusOne = 254, // 254 120 | Max, // 255 121 | MaxPlusOne // Would be 256, but that overflows the enum. 122 | } 123 | ``` 124 | 125 | ## Zero-variant Enums 126 | 127 | Enums with zero variants are known as *zero-variant enums*. As they have 128 | no valid values, they cannot be instantiated. 129 | 130 | ```rust 131 | enum ZeroVariants {} 132 | ``` 133 | 134 | Zero-variant enums are equivalent to the [never type], but they cannot be 135 | coerced into other types. 136 | 137 | ```rust,compile_fail 138 | # enum ZeroVariants {} 139 | let x: ZeroVariants = panic!(); 140 | let y: u32 = x; // mismatched type error 141 | ``` 142 | 143 | ## Variant visibility 144 | 145 | Enum variants syntactically allow a [_Visibility_] annotation, but this is 146 | rejected when the enum is validated. This allows items to be parsed with a 147 | unified syntax across different contexts where they are used. 148 | 149 | ```rust 150 | macro_rules! mac_variant { 151 | ($vis:vis $name:ident) => { 152 | enum $name { 153 | $vis Unit, 154 | 155 | $vis Tuple(u8, u16), 156 | 157 | $vis Struct { f: u8 }, 158 | } 159 | } 160 | } 161 | 162 | // Empty `vis` is allowed. 163 | mac_variant! { E } 164 | 165 | // This is allowed, since it is removed before being validated. 166 | #[cfg(FALSE)] 167 | enum E { 168 | pub U, 169 | pub(crate) T(u8), 170 | pub(super) T { f: String } 171 | } 172 | ``` 173 | 174 | [IDENTIFIER]: ../identifiers.md 175 | [_Generics_]: generics.md 176 | [_WhereClause_]: generics.md#where-clauses 177 | [_Expression_]: ../expressions.md 178 | [_TupleFields_]: structs.md 179 | [_StructFields_]: structs.md 180 | [_Visibility_]: ../visibility-and-privacy.md 181 | [enumerated type]: ../types/enum.md 182 | [`mem::discriminant`]: ../../std/mem/fn.discriminant.html 183 | [never type]: ../types/never.md 184 | [numeric cast]: ../expressions/operator-expr.md#semantics 185 | [constant expression]: ../const_eval.md#constant-expressions 186 | [default representation]: ../type-layout.md#the-default-representation 187 | [primitive representation]: ../type-layout.md#primitive-representations 188 | [`C` representation]: ../type-layout.md#the-c-representation 189 | -------------------------------------------------------------------------------- /src/items/extern-crates.md: -------------------------------------------------------------------------------- 1 | # Extern crate declarations 2 | 3 | > **Syntax:**\ 4 | > _ExternCrate_ :\ 5 | >    `extern` `crate` _CrateRef_ _AsClause_? `;` 6 | > 7 | > _CrateRef_ :\ 8 | >    [IDENTIFIER] | `self` 9 | > 10 | > _AsClause_ :\ 11 | >    `as` ( [IDENTIFIER] | `_` ) 12 | 13 | An _`extern crate` declaration_ specifies a dependency on an external crate. 14 | The external crate is then bound into the declaring scope as the [identifier] 15 | provided in the `extern crate` declaration. The `as` clause can be used to 16 | bind the imported crate to a different name. 17 | 18 | The external crate is resolved to a specific `soname` at compile time, and a 19 | runtime linkage requirement to that `soname` is passed to the linker for 20 | loading at runtime. The `soname` is resolved at compile time by scanning the 21 | compiler's library path and matching the optional `crateid` provided against 22 | the `crateid` attributes that were declared on the external crate when it was 23 | compiled. If no `crateid` is provided, a default `name` attribute is assumed, 24 | equal to the [identifier] given in the `extern crate` declaration. 25 | 26 | The `self` crate may be imported which creates a binding to the current crate. 27 | In this case the `as` clause must be used to specify the name to bind it to. 28 | 29 | Three examples of `extern crate` declarations: 30 | 31 | 32 | ```rust,ignore 33 | extern crate pcre; 34 | 35 | extern crate std; // equivalent to: extern crate std as std; 36 | 37 | extern crate std as ruststd; // linking to 'std' under another name 38 | ``` 39 | 40 | When naming Rust crates, hyphens are disallowed. However, Cargo packages may 41 | make use of them. In such case, when `Cargo.toml` doesn't specify a crate name, 42 | Cargo will transparently replace `-` with `_` (Refer to [RFC 940] for more 43 | details). 44 | 45 | Here is an example: 46 | 47 | 48 | ```rust,ignore 49 | // Importing the Cargo package hello-world 50 | extern crate hello_world; // hyphen replaced with an underscore 51 | ``` 52 | 53 | ## Extern Prelude 54 | 55 | External crates imported with `extern crate` in the root module or provided to 56 | the compiler (as with the `--extern` flag with `rustc`) are added to the 57 | "extern prelude". Crates in the extern prelude are in scope in the entire 58 | crate, including inner modules. If imported with `extern crate orig_name as 59 | new_name`, then the symbol `new_name` is instead added to the prelude. 60 | 61 | The `core` crate is always added to the extern prelude. The `std` crate 62 | is added as long as the [`no_std`] attribute is not specified in the crate root. 63 | 64 | The [`no_implicit_prelude`] attribute can be used on a module to disable 65 | prelude lookups within that module. 66 | 67 | > **Edition Differences**: In the 2015 edition, crates in the extern prelude 68 | > cannot be referenced via [use declarations], so it is generally standard 69 | > practice to include `extern crate` declarations to bring them into scope. 70 | > 71 | > Beginning in the 2018 edition, [use declarations] can reference crates in 72 | > the extern prelude, so it is considered unidiomatic to use `extern crate`. 73 | 74 | > **Note**: Additional crates that ship with `rustc`, such as [`proc_macro`], 75 | > [`alloc`], and [`test`], are not automatically included with the `--extern` 76 | > flag when using Cargo. They must be brought into scope with an `extern 77 | > crate` declaration, even in the 2018 edition. 78 | > 79 | > ```rust 80 | > extern crate proc_macro; 81 | > use proc_macro::TokenStream; 82 | > ``` 83 | 84 | 90 | 91 | ## Underscore Imports 92 | 93 | An external crate dependency can be declared without binding its name in scope 94 | by using an underscore with the form `extern crate foo as _`. This may be 95 | useful for crates that only need to be linked, but are never referenced, and 96 | will avoid being reported as unused. 97 | 98 | The [`macro_use` attribute] works as usual and import the macro names 99 | into the macro-use prelude. 100 | 101 | ## The `no_link` attribute 102 | 103 | The *`no_link` attribute* may be specified on an `extern crate` item to 104 | prevent linking the crate into the output. This is commonly used to load a 105 | crate to access only its macros. 106 | 107 | [IDENTIFIER]: ../identifiers.md 108 | [RFC 940]: https://github.com/rust-lang/rfcs/blob/master/text/0940-hyphens-considered-harmful.md 109 | [`macro_use` attribute]: ../macros-by-example.md#the-macro_use-attribute 110 | [`alloc`]: https://doc.rust-lang.org/alloc/ 111 | [`no_implicit_prelude`]: modules.md#prelude-items 112 | [`no_std`]: ../crates-and-source-files.md#preludes-and-no_std 113 | [`proc_macro`]: https://doc.rust-lang.org/proc_macro/ 114 | [`test`]: https://doc.rust-lang.org/test/ 115 | [use declarations]: use-declarations.md 116 | -------------------------------------------------------------------------------- /src/items/generics.md: -------------------------------------------------------------------------------- 1 | # Type and Lifetime Parameters 2 | 3 | > **Syntax**\ 4 | > _Generics_ :\ 5 | >    `<` _GenericParams_ `>` 6 | > 7 | > _GenericParams_ :\ 8 | >       _LifetimeParams_\ 9 | >    | ( _LifetimeParam_ `,` )\* _TypeParams_ 10 | > 11 | > _LifetimeParams_ :\ 12 | >    ( _LifetimeParam_ `,` )\* _LifetimeParam_? 13 | > 14 | > _LifetimeParam_ :\ 15 | >    [_OuterAttribute_]? [LIFETIME_OR_LABEL] ( `:` [_LifetimeBounds_] )? 16 | > 17 | > _TypeParams_:\ 18 | >    ( _TypeParam_ `,` )\* _TypeParam_? 19 | > 20 | > _TypeParam_ :\ 21 | >    [_OuterAttribute_]? [IDENTIFIER] ( `:` [_TypeParamBounds_]? )? ( `=` [_Type_] )? 22 | 23 | Functions, type aliases, structs, enumerations, unions, traits, and 24 | implementations may be *parameterized* by types and lifetimes. These parameters 25 | are listed in angle brackets (`<...>`), 26 | usually immediately after the name of the item and before its definition. For 27 | implementations, which don't have a name, they come directly after `impl`. 28 | Lifetime parameters must be declared before type parameters. Some examples of 29 | items with type and lifetime parameters: 30 | 31 | ```rust 32 | fn foo<'a, T>() {} 33 | trait A {} 34 | struct Ref<'a, T> where T: 'a { r: &'a T } 35 | ``` 36 | 37 | [References], [raw pointers], [arrays], [slices][arrays], [tuples], and 38 | [function pointers] have lifetime or type parameters as well, but are not 39 | referred to with path syntax. 40 | 41 | ## Where clauses 42 | 43 | > **Syntax**\ 44 | > _WhereClause_ :\ 45 | >    `where` ( _WhereClauseItem_ `,` )\* _WhereClauseItem_ ? 46 | > 47 | > _WhereClauseItem_ :\ 48 | >       _LifetimeWhereClauseItem_\ 49 | >    | _TypeBoundWhereClauseItem_ 50 | > 51 | > _LifetimeWhereClauseItem_ :\ 52 | >    [_Lifetime_] `:` [_LifetimeBounds_] 53 | > 54 | > _TypeBoundWhereClauseItem_ :\ 55 | >    _ForLifetimes_? [_Type_] `:` [_TypeParamBounds_]? 56 | > 57 | > _ForLifetimes_ :\ 58 | >    `for` `<` [_LifetimeParams_](#type-and-lifetime-parameters) `>` 59 | 60 | *Where clauses* provide another way to specify bounds on type and lifetime 61 | parameters as well as a way to specify bounds on types that aren't type 62 | parameters. 63 | 64 | Bounds that don't use the item's parameters or higher-ranked lifetimes are 65 | checked when the item is defined. It is an error for such a bound to be false. 66 | 67 | [`Copy`], [`Clone`], and [`Sized`] bounds are also checked for certain generic 68 | types when defining the item. It is an error to have `Copy` or `Clone`as a 69 | bound on a mutable reference, [trait object] or [slice][arrays] or `Sized` as a 70 | bound on a trait object or slice. 71 | 72 | ```rust,compile_fail 73 | struct A 74 | where 75 | T: Iterator, // Could use A instead 76 | T::Item: Copy, 77 | String: PartialEq, 78 | i32: Default, // Allowed, but not useful 79 | i32: Iterator, // Error: the trait bound is not satisfied 80 | [T]: Copy, // Error: the trait bound is not satisfied 81 | { 82 | f: T, 83 | } 84 | ``` 85 | 86 | ## Attributes 87 | 88 | Generic lifetime and type parameters allow [attributes] on them. There are no 89 | built-in attributes that do anything in this position, although custom derive 90 | attributes may give meaning to it. 91 | 92 | This example shows using a custom derive attribute to modify the meaning of a 93 | generic parameter. 94 | 95 | 96 | ```rust,ignore 97 | // Assume that the derive for MyFlexibleClone declared `my_flexible_clone` as 98 | // an attribute it understands. 99 | #[derive(MyFlexibleClone)] 100 | struct Foo<#[my_flexible_clone(unbounded)] H> { 101 | a: *const H 102 | } 103 | ``` 104 | 105 | [IDENTIFIER]: ../identifiers.md 106 | [LIFETIME_OR_LABEL]: ../tokens.md#lifetimes-and-loop-labels 107 | 108 | [_LifetimeBounds_]: ../trait-bounds.md 109 | [_Lifetime_]: ../trait-bounds.md 110 | [_OuterAttribute_]: ../attributes.md 111 | [_Type_]: ../types.md#type-expressions 112 | [_TypeParamBounds_]: ../trait-bounds.md 113 | 114 | [arrays]: ../types/array.md 115 | [function pointers]: ../types/function-pointer.md 116 | [references]: ../types/pointer.md#shared-references- 117 | [raw pointers]: ../types/pointer.md#raw-pointers-const-and-mut 118 | [`Clone`]: ../special-types-and-traits.md#clone 119 | [`Copy`]: ../special-types-and-traits.md#copy 120 | [`Sized`]: ../special-types-and-traits.md#sized 121 | [tuples]: ../types/tuple.md 122 | [trait object]: ../types/trait-object.md 123 | [attributes]: ../attributes.md 124 | -------------------------------------------------------------------------------- /src/items/modules.md: -------------------------------------------------------------------------------- 1 | # 模块 2 | · 3 | > [items/modules.md](https://github.com/rust-lang/reference/blob/master/src/items/modules.md) 4 | >
5 | > commit - f8e76ee9368f498f7f044c719de68c7d95da9972 - 2019-11-08 6 | 7 | > **Syntax:**\ 8 | > _Module_ :\ 9 | >       `mod` [IDENTIFIER] `;`\ 10 | >    | `mod` [IDENTIFIER] `{`\ 11 | >         [_InnerAttribute_]\*\ 12 | >         [_Item_]\*\ 13 | >       `}` 14 | 15 | 模块是零个或多个[项][items]的容器。 16 | 17 | *模块项* 是一个模块,包含在大括号中,需要命名,并以关键字 `mod` 作为前缀。模块项将一个新的命名模块引入到组成 crate 的模块树中。模块可以任意嵌套。 18 | 19 | 模块示例: 20 | 21 | ```rust 22 | mod math { 23 | type Complex = (f64, f64); 24 | fn sin(f: f64) -> f64 { 25 | /* ... */ 26 | # unimplemented!(); 27 | } 28 | fn cos(f: f64) -> f64 { 29 | /* ... */ 30 | # unimplemented!(); 31 | } 32 | fn tan(f: f64) -> f64 { 33 | /* ... */ 34 | # unimplemented!(); 35 | } 36 | } 37 | ``` 38 | 39 | 模块和类型共享相同的命名空间。禁止在作用域中声明与模块同名的命名类型,即:类型定义、trait、结构体、枚举、联合体、类型参数或 crate 不能遮蔽作用域中模块的名称,反之亦然。使用 `use` 纳入作用域的项同样有此限制。 40 | 41 | ## 模块的源文件名字 42 | 43 | 从外部文件加载没有主体的模块。当模块没有 `path` 属性时,文件的路径将镜像逻辑[模块路径][module 44 | path]。原型模块路径组件是目录,且模块的内容位于一个具有模块名称和 `.rs` 扩展名的文件中。例如,如下模块结构具有相应的文件系统结构: 45 | 46 | 模块路径 | 文件系统路径 | 文件内容 47 | ------------------------- | --------------- | ------------- 48 | `crate` | `lib.rs` | `mod util;` 49 | `crate::util` | `util.rs` | `mod config;` 50 | `crate::util::config` | `util/config.rs` | 51 | 52 | 目录也可以作为模块,目录名既是模块文件名,该目录包含一个名为 `mod.rs` 的文件。上面例子中模块路径 `crate::util` 可以将文件系统路径替换表达为 `util/mod.rs`。不允许 `util.rs` 和 `util/mod.rs` 同时存在。 53 | 54 | > **注**:在 `rustc` 1.30 之前,使用 `mod.rs` 文件是加载具有嵌套的子级模块的方法。鼓励使用新的命名约定,因为它更加一致,并且避免在一个项目中有许多文件被命名为 `mod.rs`。 55 | 56 | ### `path` 属性 57 | 58 | 用于加载外部文件模块的目录和文件可以被 `path` 属性影响。 59 | 60 | 对于不在内联模块体内的模块上的 `path` 属性,文件路径为相对于源文件所在的目录。例如,以下代码段将使用基于其所在位置的路径: 61 | 62 | 63 | ```rust,ignore 64 | #[path = "foo.rs"] 65 | mod c; 66 | ``` 67 | 68 | 源文件 | `c` 的文件位置 | `c` 的模块路径 69 | -------------- | ------------------- | ---------------------- 70 | `src/a/b.rs` | `src/a/foo.rs` | `crate::a::b::c` 71 | `src/a/mod.rs` | `src/a/foo.rs` | `crate::a::c` 72 | 73 | 对于内联模块体内的 `path` 属性,文件路径的相对位置取决于 `path` 属性所在的源文件的类型。“mod-rs” 源文件是根模块(例如 `lib.rs` 或者 `main.rs`)和具有 `mod.rs` 文件的模块,“non-mod-rs” 源文件是其他模块文件。mod-rs 文件中的内联模块体内的 `path` 属性的路径为相对于 mod-rs 文件的目录,包括作为目录的内联模块组件。对于 non-mod-rs 文件,除了路径以具有 non-mod-rs 模块名称的目录开头外,其它都是相同的。例如,以下代码段将使用基于其所在位置的路径: 74 | 75 | 76 | ```rust,ignore 77 | mod inline { 78 | #[path = "other.rs"] 79 | mod inner; 80 | } 81 | ``` 82 | 83 | 源文件 | `内联`' 的文件位置 | `内联`' 的模块路径 84 | -------------- | --------------------------| ---------------------------- 85 | `src/a/b.rs` | `src/a/b/inline/other.rs` | `crate::a::b::inline::inner` 86 | `src/a/mod.rs` | `src/a/inline/other.rs` | `crate::a::inline::inner` 87 | 88 | 在内联模块和内部嵌套模块上组合上述 `path` 属性规则的示例(mod-rs 和 non-mod-rs 文件都适用): 89 | 90 | 91 | ```rust,ignore 92 | #[path = "thread_files"] 93 | mod thread { 94 | // Load the `local_data` module from `thread_files/tls.rs` relative to 95 | // this source file's directory. 96 | #[path = "tls.rs"] 97 | mod local_data; 98 | } 99 | ``` 100 | 101 | ## prelude 项 102 | 103 | 模块在作用域中隐式地有一些名称。这些名称是内建类型、宏,在外部 crate 上使用 [`#[macro_use]`][macro_use],以及 crate 的 [prelude] 导入。这些名称都由一个标识符组成。这些名称不是模块的一部分,因此——比如说——任何名称 `name`,`self::name` 均不是有效路径。通过在模块或其父模块中放置 `no_implicit_prelude` [属性][attribute],可以移除由 [prelude] 添加的名称。 104 | 105 | ## 模块的属性 106 | 107 | 和所有项类似,模块也接受外部属性。模块还接受内部属性:要么在 `{` 之后(具有主体的模块文件中),要么在源文件开头——可选的字节顺序标记(BOM)和释伴(shebang)之后。 108 | 109 | 对模块有意义的内建属性包括:[`cfg`]、[`deprecated`]、[`doc`]、[lint 检查属性][the lint check attributes]、`path`,以及 `no_implicit_prelude`。模块也接受宏属性。 110 | 111 | [_InnerAttribute_]: ../attributes.md 112 | [_Item_]: ../items.md 113 | [macro_use]: ../macros-by-example.md#the-macro_use-attribute 114 | [`cfg`]: ../conditional-compilation.md 115 | [`deprecated`]: ../attributes/diagnostics.md#the-deprecated-attribute 116 | [`doc`]: ../../rustdoc/the-doc-attribute.html 117 | [IDENTIFIER]: ../identifiers.md 118 | [attribute]: ../attributes.md 119 | [items]: ../items.md 120 | [module path]: ../paths.md 121 | [prelude]: ../crates-and-source-files.md#preludes-and-no_std 122 | [the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes 123 | -------------------------------------------------------------------------------- /src/items/static-items.md: -------------------------------------------------------------------------------- 1 | # Static items 2 | 3 | > **Syntax**\ 4 | > _StaticItem_ :\ 5 | >    `static` `mut`? [IDENTIFIER] `:` [_Type_] 6 | > `=` [_Expression_] `;` 7 | 8 | A *static item* is similar to a [constant], except that it represents a precise 9 | memory location in the program. All references to the static refer to the same 10 | memory location. Static items have the `static` lifetime, which outlives all 11 | other lifetimes in a Rust program. Non-`mut` static items that contain a type 12 | that is not [interior mutable] may be placed in read-only memory. Static items 13 | do not call [`drop`] at the end of the program. 14 | 15 | All access to a static is safe, but there are a number of restrictions on 16 | statics: 17 | 18 | * The type must have the `Sync` trait bound to allow thread-safe access. 19 | * Statics allow using paths to statics in the [constant expression] used to 20 | initialize them, but statics may not refer to other statics by value, only 21 | through a reference. 22 | * Constants cannot refer to statics. 23 | 24 | ## Mutable statics 25 | 26 | If a static item is declared with the `mut` keyword, then it is allowed to be 27 | modified by the program. One of Rust's goals is to make concurrency bugs hard 28 | to run into, and this is obviously a very large source of race conditions or 29 | other bugs. For this reason, an `unsafe` block is required when either reading 30 | or writing a mutable static variable. Care should be taken to ensure that 31 | modifications to a mutable static are safe with respect to other threads 32 | running in the same process. 33 | 34 | Mutable statics are still very useful, however. They can be used with C 35 | libraries and can also be bound from C libraries in an `extern` block. 36 | 37 | ```rust 38 | # fn atomic_add(_: &mut u32, _: u32) -> u32 { 2 } 39 | 40 | static mut LEVELS: u32 = 0; 41 | 42 | // This violates the idea of no shared state, and this doesn't internally 43 | // protect against races, so this function is `unsafe` 44 | unsafe fn bump_levels_unsafe1() -> u32 { 45 | let ret = LEVELS; 46 | LEVELS += 1; 47 | return ret; 48 | } 49 | 50 | // Assuming that we have an atomic_add function which returns the old value, 51 | // this function is "safe" but the meaning of the return value may not be what 52 | // callers expect, so it's still marked as `unsafe` 53 | unsafe fn bump_levels_unsafe2() -> u32 { 54 | return atomic_add(&mut LEVELS, 1); 55 | } 56 | ``` 57 | 58 | Mutable statics have the same restrictions as normal statics, except that the 59 | type does not have to implement the `Sync` trait. 60 | 61 | ## Using Statics or Consts 62 | 63 | It can be confusing whether or not you should use a constant item or a static 64 | item. Constants should, in general, be preferred over statics unless one of the 65 | following are true: 66 | 67 | * Large amounts of data are being stored 68 | * The single-address property of statics is required. 69 | * Interior mutability is required. 70 | 71 | [constant]: constant-items.md 72 | [`drop`]: ../destructors.md 73 | [constant expression]: ../const_eval.md#constant-expressions 74 | [interior mutable]: ../interior-mutability.md 75 | [IDENTIFIER]: ../identifiers.md 76 | [_Type_]: ../types.md#type-expressions 77 | [_Expression_]: ../expressions.md 78 | -------------------------------------------------------------------------------- /src/items/structs.md: -------------------------------------------------------------------------------- 1 | # Structs 2 | 3 | > **Syntax**\ 4 | > _Struct_ :\ 5 | >       _StructStruct_\ 6 | >    | _TupleStruct_ 7 | > 8 | > _StructStruct_ :\ 9 | >    `struct` 10 | > [IDENTIFIER]  11 | > [_Generics_]? 12 | > [_WhereClause_]? 13 | > ( `{` _StructFields_? `}` | `;` ) 14 | > 15 | > _TupleStruct_ :\ 16 | >    `struct` 17 | > [IDENTIFIER]  18 | > [_Generics_]? 19 | > `(` _TupleFields_? `)` 20 | > [_WhereClause_]? 21 | > `;` 22 | > 23 | > _StructFields_ :\ 24 | >    _StructField_ (`,` _StructField_)\* `,`? 25 | > 26 | > _StructField_ :\ 27 | >    [_OuterAttribute_]\*\ 28 | >    [_Visibility_]?\ 29 | >    [IDENTIFIER] `:` [_Type_] 30 | > 31 | > _TupleFields_ :\ 32 | >    _TupleField_ (`,` _TupleField_)\* `,`? 33 | > 34 | > _TupleField_ :\ 35 | >    [_OuterAttribute_]\*\ 36 | >    [_Visibility_]?\ 37 | >    [_Type_] 38 | 39 | A _struct_ is a nominal [struct type] defined with the keyword `struct`. 40 | 41 | An example of a `struct` item and its use: 42 | 43 | ```rust 44 | struct Point {x: i32, y: i32} 45 | let p = Point {x: 10, y: 11}; 46 | let px: i32 = p.x; 47 | ``` 48 | 49 | A _tuple struct_ is a nominal [tuple type], also defined with the keyword 50 | `struct`. For example: 51 | 52 | [struct type]: ../types/struct.md 53 | [tuple type]: ../types/tuple.md 54 | 55 | ```rust 56 | struct Point(i32, i32); 57 | let p = Point(10, 11); 58 | let px: i32 = match p { Point(x, _) => x }; 59 | ``` 60 | 61 | A _unit-like struct_ is a struct without any fields, defined by leaving off the 62 | list of fields entirely. Such a struct implicitly defines a constant of its 63 | type with the same name. For example: 64 | 65 | ```rust 66 | struct Cookie; 67 | let c = [Cookie, Cookie {}, Cookie, Cookie {}]; 68 | ``` 69 | 70 | is equivalent to 71 | 72 | ```rust 73 | struct Cookie {} 74 | const Cookie: Cookie = Cookie {}; 75 | let c = [Cookie, Cookie {}, Cookie, Cookie {}]; 76 | ``` 77 | 78 | The precise memory layout of a struct is not specified. One can specify a 79 | particular layout using the [`repr` attribute]. 80 | 81 | [`repr` attribute]: ../type-layout.md#representations 82 | 83 | [_OuterAttribute_]: ../attributes.md 84 | [IDENTIFIER]: ../identifiers.md 85 | [_Generics_]: generics.md 86 | [_WhereClause_]: generics.md#where-clauses 87 | [_Visibility_]: ../visibility-and-privacy.md 88 | [_Type_]: ../types.md#type-expressions 89 | -------------------------------------------------------------------------------- /src/items/type-aliases.md: -------------------------------------------------------------------------------- 1 | # Type aliases 2 | 3 | > **Syntax**\ 4 | > _TypeAlias_ :\ 5 | >    `type` [IDENTIFIER] [_Generics_]? 6 | > [_WhereClause_]? `=` [_Type_] `;` 7 | 8 | A _type alias_ defines a new name for an existing [type]. Type aliases are 9 | declared with the keyword `type`. Every value has a single, specific type, but 10 | may implement several different traits, or be compatible with several different 11 | type constraints. 12 | 13 | [type]: ../types.md 14 | 15 | For example, the following defines the type `Point` as a synonym for the type 16 | `(u8, u8)`, the type of pairs of unsigned 8 bit integers: 17 | 18 | ```rust 19 | type Point = (u8, u8); 20 | let p: Point = (41, 68); 21 | ``` 22 | 23 | A type alias to an enum type cannot be used to qualify the constructors: 24 | 25 | ```rust 26 | enum E { A } 27 | type F = E; 28 | let _: F = E::A; // OK 29 | // let _: F = F::A; // Doesn't work 30 | ``` 31 | 32 | [IDENTIFIER]: ../identifiers.md 33 | [_Generics_]: generics.md 34 | [_WhereClause_]: generics.md#where-clauses 35 | [_Type_]: ../types.md#type-expressions 36 | -------------------------------------------------------------------------------- /src/items/unions.md: -------------------------------------------------------------------------------- 1 | # Unions 2 | 3 | > **Syntax**\ 4 | > _Union_ :\ 5 | >    `union` [IDENTIFIER] [_Generics_]? [_WhereClause_]? 6 | > `{`[_StructFields_] `}` 7 | 8 | A union declaration uses the same syntax as a struct declaration, except with 9 | `union` in place of `struct`. 10 | 11 | ```rust 12 | #[repr(C)] 13 | union MyUnion { 14 | f1: u32, 15 | f2: f32, 16 | } 17 | ``` 18 | 19 | The key property of unions is that all fields of a union share common storage. 20 | As a result writes to one field of a union can overwrite its other fields, and 21 | size of a union is determined by the size of its largest field. 22 | 23 | ## Initialization of a union 24 | 25 | A value of a union type can be created using the same syntax that is used for 26 | struct types, except that it must specify exactly one field: 27 | 28 | ```rust 29 | # union MyUnion { f1: u32, f2: f32 } 30 | # 31 | let u = MyUnion { f1: 1 }; 32 | ``` 33 | 34 | The expression above creates a value of type `MyUnion` and initializes the 35 | storage using field `f1`. The union can be accessed using the same syntax as 36 | struct fields: 37 | 38 | ```rust 39 | # union MyUnion { f1: u32, f2: f32 } 40 | # 41 | # let u = MyUnion { f1: 1 }; 42 | let f = unsafe { u.f1 }; 43 | ``` 44 | 45 | ## Reading and writing union fields 46 | 47 | Unions have no notion of an "active field". Instead, every union access just 48 | interprets the storage at the type of the field used for the access. Reading a 49 | union field reads the bits of the union at the field's type. Fields might have a 50 | non-zero offset (except when `#[repr(C)]` is used); in that case the bits 51 | starting at the offset of the fields are read. It is the programmer's 52 | responsibility to make sure that the data is valid at the field's type. Failing 53 | to do so results in undefined behavior. For example, reading the value `3` at 54 | type `bool` is undefined behavior. Effectively, writing to and then reading from 55 | a `#[repr(C)]` union is analogous to a [`transmute`] from the type used for 56 | writing to the type used for reading. 57 | 58 | Consequently, all reads of union fields have to be placed in `unsafe` blocks: 59 | 60 | ```rust 61 | # union MyUnion { f1: u32, f2: f32 } 62 | # let u = MyUnion { f1: 1 }; 63 | # 64 | unsafe { 65 | let f = u.f1; 66 | } 67 | ``` 68 | 69 | Writes to `Copy` union fields do not require reads for running destructors, so 70 | these writes don't have to be placed in `unsafe` blocks 71 | 72 | ```rust 73 | # union MyUnion { f1: u32, f2: f32 } 74 | # let mut u = MyUnion { f1: 1 }; 75 | # 76 | u.f1 = 2; 77 | ``` 78 | 79 | Commonly, code using unions will provide safe wrappers around unsafe union 80 | field accesses. 81 | 82 | ## Pattern matching on unions 83 | 84 | Another way to access union fields is to use pattern matching. Pattern matching 85 | on union fields uses the same syntax as struct patterns, except that the pattern 86 | must specify exactly one field. Since pattern matching is like reading the union 87 | with a particular field, it has to be placed in `unsafe` blocks as well. 88 | 89 | ```rust 90 | # union MyUnion { f1: u32, f2: f32 } 91 | # 92 | fn f(u: MyUnion) { 93 | unsafe { 94 | match u { 95 | MyUnion { f1: 10 } => { println!("ten"); } 96 | MyUnion { f2 } => { println!("{}", f2); } 97 | } 98 | } 99 | } 100 | ``` 101 | 102 | Pattern matching may match a union as a field of a larger structure. In 103 | particular, when using a Rust union to implement a C tagged union via FFI, this 104 | allows matching on the tag and the corresponding field simultaneously: 105 | 106 | ```rust 107 | #[repr(u32)] 108 | enum Tag { I, F } 109 | 110 | #[repr(C)] 111 | union U { 112 | i: i32, 113 | f: f32, 114 | } 115 | 116 | #[repr(C)] 117 | struct Value { 118 | tag: Tag, 119 | u: U, 120 | } 121 | 122 | fn is_zero(v: Value) -> bool { 123 | unsafe { 124 | match v { 125 | Value { tag: Tag::I, u: U { i: 0 } } => true, 126 | Value { tag: Tag::F, u: U { f: num } } if num == 0.0 => true, 127 | _ => false, 128 | } 129 | } 130 | } 131 | ``` 132 | 133 | ## References to union fields 134 | 135 | Since union fields share common storage, gaining write access to one field of a 136 | union can give write access to all its remaining fields. Borrow checking rules 137 | have to be adjusted to account for this fact. As a result, if one field of a 138 | union is borrowed, all its remaining fields are borrowed as well for the same 139 | lifetime. 140 | 141 | ```rust,compile_fail 142 | # union MyUnion { f1: u32, f2: f32 } 143 | // ERROR: cannot borrow `u` (via `u.f2`) as mutable more than once at a time 144 | fn test() { 145 | let mut u = MyUnion { f1: 1 }; 146 | unsafe { 147 | let b1 = &mut u.f1; 148 | // ---- first mutable borrow occurs here (via `u.f1`) 149 | let b2 = &mut u.f2; 150 | // ^^^^ second mutable borrow occurs here (via `u.f2`) 151 | *b1 = 5; 152 | } 153 | // - first borrow ends here 154 | assert_eq!(unsafe { u.f1 }, 5); 155 | } 156 | ``` 157 | 158 | As you could see, in many aspects (except for layouts, safety, and ownership) 159 | unions behave exactly like structs, largely as a consequence of inheriting 160 | their syntactic shape from structs. This is also true for many unmentioned 161 | aspects of Rust language (such as privacy, name resolution, type inference, 162 | generics, trait implementations, inherent implementations, coherence, pattern 163 | checking, etc etc etc). 164 | 165 | [IDENTIFIER]: ../identifiers.md 166 | [_Generics_]: generics.md 167 | [_WhereClause_]: generics.md#where-clauses 168 | [_StructFields_]: structs.md 169 | [`transmute`]: ../../std/mem/fn.transmute.html 170 | -------------------------------------------------------------------------------- /src/keywords.md: -------------------------------------------------------------------------------- 1 | # 关键字 2 | 3 | > [keywords.md](https://github.com/rust-lang/reference/blob/master/src/keywords.md) 4 | >
5 | > commit 64923185890763048d190ce92cb668b58acbc49a 6 | 7 | Rust 将关键字分为三类: 8 | 9 | * [规定关键字](#规定关键字) 10 | * [保留关键字](#保留关键字) 11 | * [弱待修正关键字](#弱sup待修正sup关键字) 12 | 13 | > *译者注*:下文 `KW` 为 keywords 的简写。 14 | 15 | ## 规定关键字 16 | 17 | 规定关键字仅能在正确的上下文中使用。它们不能用作: 18 | 19 | * [项][Items] 20 | * [变量][Variables]和函数参数 21 | * 字段和[枚举][enumerations] 22 | * [类型参数][Type parameters] 23 | * 生命周期参数或者[循环标签][loop labels] 24 | * [宏][Macros]或[属性][attributes] 25 | * [宏占位符][Macro placeholders] 26 | * [crate 和源文件][Crates] 27 | 28 | > **Lexer:**\ 29 | > KW_AS : `as`\ 30 | > KW_BREAK : `break`\ 31 | > KW_CONST : `const`\ 32 | > KW_CONTINUE : `continue`\ 33 | > KW_CRATE : `crate`\ 34 | > KW_ELSE : `else`\ 35 | > KW_ENUM : `enum`\ 36 | > KW_EXTERN : `extern`\ 37 | > KW_FALSE : `false`\ 38 | > KW_FN : `fn`\ 39 | > KW_FOR : `for`\ 40 | > KW_IF : `if`\ 41 | > KW_IMPL : `impl`\ 42 | > KW_IN : `in`\ 43 | > KW_LET : `let`\ 44 | > KW_LOOP : `loop`\ 45 | > KW_MATCH : `match`\ 46 | > KW_MOD : `mod`\ 47 | > KW_MOVE : `move`\ 48 | > KW_MUT : `mut`\ 49 | > KW_PUB : `pub`\ 50 | > KW_REF : `ref`\ 51 | > KW_RETURN : `return`\ 52 | > KW_SELFVALUE : `self`\ 53 | > KW_SELFTYPE : `Self`\ 54 | > KW_STATIC : `static`\ 55 | > KW_STRUCT : `struct`\ 56 | > KW_SUPER : `super`\ 57 | > KW_TRAIT : `trait`\ 58 | > KW_TRUE : `true`\ 59 | > KW_TYPE : `type`\ 60 | > KW_UNSAFE : `unsafe`\ 61 | > KW_USE : `use`\ 62 | > KW_WHERE : `where`\ 63 | > KW_WHILE : `while` 64 | 65 | 2018 版本增加了下述规定关键字。 66 | 67 | > **Lexer 2018+**\ 68 | > KW_ASYNC : `async`\ 69 | > KW_AWAIT : `await`\ 70 | > KW_DYN : `dyn` 71 | 72 | ## 保留关键字 73 | 74 | 保留关键字尚未使用,但已保留供将来使用。它们与严格的关键字有相同的限制。其背后的原因是,禁止当前程序使用这些关键字,从而使当前程序与未来版本的 Rust 兼容。 75 | 76 | > **Lexer**\ 77 | > KW_ABSTRACT : `abstract`\ 78 | > KW_BECOME : `become`\ 79 | > KW_BOX : `box`\ 80 | > KW_DO : `do`\ 81 | > KW_FINAL : `final`\ 82 | > KW_MACRO : `macro`\ 83 | > KW_OVERRIDE : `override`\ 84 | > KW_PRIV : `priv`\ 85 | > KW_TYPEOF : `typeof`\ 86 | > KW_UNSIZED : `unsized`\ 87 | > KW_VIRTUAL : `virtual`\ 88 | > KW_YIELD : `yield` 89 | 90 | 2018 版本增加了下述保留关键字。 91 | 92 | > **Lexer 2018+**\ 93 | > KW_TRY : `try` 94 | 95 | ## 弱待修正关键字 96 | 97 | 弱待修正关键字仅在特定的上下文中才有特殊的含义。例如,可以声明一个名为 `union` 的变量或方法。 98 | 99 | * `union` 用来声明一个[联合体][union],且仅在联合体声明中是关键字。 100 | * `'static` 用于静态生命周期,且不能用作泛型生命周期参数。 101 | 102 | ```compile_fail 103 | // error[E0262]: invalid lifetime parameter name: `'static` 104 | fn invalid_lifetime_parameter<'static>(s: &'static str) -> &'static str { s } 105 | ``` 106 | * 2015 版本中,[`dyn`] 是一个关键字,当在类型位置使用时,其后跟随的路径不能以 `::` 开头。 107 | 108 | 自 2018 版本开始,`dyn` 被提升为规定关键字。 109 | 110 | > **Lexer**\ 111 | > KW_UNION : `union`\ 112 | > KW_STATICLIFETIME : `'static` 113 | > 114 | > **Lexer 2015**\ 115 | > KW_DYN : `dyn` 116 | 117 | [items]: items.md 118 | [Variables]: variables.md 119 | [Type parameters]: types/parameters.md 120 | [loop labels]: expressions/loop-expr.md#loop-labels 121 | [Macros]: macros.md 122 | [attributes]: attributes.md 123 | [Macro placeholders]: macros-by-example.md 124 | [Crates]: crates-and-source-files.md 125 | [union]: items/unions.md 126 | [enumerations]: items/enumerations.md 127 | [`dyn`]: types/trait-object.md 128 | -------------------------------------------------------------------------------- /src/lexical-structure.md: -------------------------------------------------------------------------------- 1 | # 词法结构 2 | 3 | > [lexical-structure.md](https://github.com/rust-lang/reference/blob/master/src/lexical-structure.md) 4 | >
5 | > commit 4a2bdf896cd2df370a91d14cb8ba04e326cd21db 6 | -------------------------------------------------------------------------------- /src/macros.md: -------------------------------------------------------------------------------- 1 | # 宏 2 | 3 | > [macros.md](https://github.com/rust-lang/reference/blob/master/src/macros.md) 4 | >
5 | > commit 771c5d10cf944bf7d221f5d6cb7abd2a06c400e4 6 | 7 | Rust 语言的功能和语法可以通过自定义宏进行扩展。宏可以被命名,可通过一致的语法调用:`some_extension!(...)`。 8 | 9 | 定义新宏有两种方式: 10 | 11 | * [声明宏][Macros by Example]以更高级别的声明性方式定义新语法。 12 | * [过程宏][Procedural Macros]可用于实现自定义派生。 13 | 14 | ## 宏调用 15 | 16 | > **Syntax**\ 17 | > _MacroInvocation_ :\ 18 | >    [_SimplePath_] `!` _DelimTokenTree_ 19 | > 20 | > _DelimTokenTree_ :\ 21 | >       `(` _TokenTree_\* `)`\ 22 | >    | `[` _TokenTree_\* `]`\ 23 | >    | `{` _TokenTree_\* `}` 24 | > 25 | > _TokenTree_ :\ 26 | >    [_Token_]_except [delimiters]_ | _DelimTokenTree_ 27 | > 28 | > _MacroInvocationSemi_ :\ 29 | >       [_SimplePath_] `!` `(` _TokenTree_\* `)` `;`\ 30 | >    | [_SimplePath_] `!` `[` _TokenTree_\* `]` `;`\ 31 | >    | [_SimplePath_] `!` `{` _TokenTree_\* `}` 32 | 33 | 宏调用在编译时执行宏,并用执行结果替换调用。可以在下述情况中调用宏: 34 | 35 | * [表达式][Expressions]和[语句][statements] 36 | * [模式][Patterns] 37 | * [类型][Types] 38 | * [项][Items]以及[关联项][associated items] 39 | * [`声明宏`][`macro_rules`]转换 40 | * [外部块][External blocks] 41 | 42 | 当用作项或语句时,_MacroInvocationSemi_ 形式被使用。_MacroInvocationSemi_ 形式中,如果不使用大括号,则在结尾处需要分号。在宏调用或[`声明宏`][`macro_rules`]定义之前,不允许使用[可见性限定符][Visibility qualifiers]。 43 | 44 | ```rust 45 | // Used as an expression. 46 | let x = vec![1,2,3]; 47 | 48 | // Used as a statement. 49 | println!("Hello!"); 50 | 51 | // Used in a pattern. 52 | macro_rules! pat { 53 | ($i:ident) => (Some($i)) 54 | } 55 | 56 | if let pat!(x) = Some(1) { 57 | assert_eq!(x, 1); 58 | } 59 | 60 | // Used in a type. 61 | macro_rules! Tuple { 62 | { $A:ty, $B:ty } => { ($A, $B) }; 63 | } 64 | 65 | type N2 = Tuple!(i32, i32); 66 | 67 | // Used as an item. 68 | # use std::cell::RefCell; 69 | thread_local!(static FOO: RefCell = RefCell::new(1)); 70 | 71 | // Used as an associated item. 72 | macro_rules! const_maker { 73 | ($t:ty, $v:tt) => { const CONST: $t = $v; }; 74 | } 75 | trait T { 76 | const_maker!{i32, 7} 77 | } 78 | 79 | // Macro calls within macros. 80 | macro_rules! example { 81 | () => { println!("Macro call in a macro!") }; 82 | } 83 | // Outer macro `example` is expanded, then inner macro `println` is expanded. 84 | example!(); 85 | ``` 86 | 87 | [Macros by Example]: macros-by-example.md 88 | [Procedural Macros]: procedural-macros.md 89 | [_SimplePath_]: paths.md#simple-paths 90 | [_Token_]: tokens.md 91 | [associated items]: items/associated-items.md 92 | [delimiters]: tokens.md#delimiters 93 | [expressions]: expressions.md 94 | [items]: items.md 95 | [`macro_rules`]: macros-by-example.md 96 | [patterns]: patterns.md 97 | [statements]: statements.md 98 | [types]: types.md 99 | [visibility qualifiers]: visibility-and-privacy.md 100 | [External blocks]: items/external-blocks.md 101 | -------------------------------------------------------------------------------- /src/memory-allocation-and-lifetime.md: -------------------------------------------------------------------------------- 1 | # Memory allocation and lifetime 2 | 3 | The _items_ of a program are those functions, modules, and types that have their 4 | value calculated at compile-time and stored uniquely in the memory image of the 5 | rust process. Items are neither dynamically allocated nor freed. 6 | 7 | The _heap_ is a general term that describes boxes. The lifetime of an 8 | allocation in the heap depends on the lifetime of the box values pointing to 9 | it. Since box values may themselves be passed in and out of frames, or stored 10 | in the heap, heap allocations may outlive the frame they are allocated within. 11 | An allocation in the heap is guaranteed to reside at a single location in the 12 | heap for the whole lifetime of the allocation - it will never be relocated as 13 | a result of moving a box value. 14 | -------------------------------------------------------------------------------- /src/memory-model.md: -------------------------------------------------------------------------------- 1 | # Memory model 2 | 3 | Rust does not yet have a defined memory model. Various academics and industry 4 | are working on various proposals, but for now, this is an under-defined place 5 | in the language. 6 | -------------------------------------------------------------------------------- /src/memory-ownership.md: -------------------------------------------------------------------------------- 1 | ## Memory ownership 2 | 3 | When a stack frame is exited, its local allocations are all released, and its 4 | references to boxes are dropped. 5 | -------------------------------------------------------------------------------- /src/notation.md: -------------------------------------------------------------------------------- 1 | # 标记法 2 | 3 | > [notation.md](https://github.com/rust-lang/reference/blob/master/src/notation.md) 4 | >
5 | > commit b0e0ad6490d6517c19546b1023948986578fc378 6 | 7 | ## 语法 8 | 9 | 下表符号被用于 *Lexer* 和 *Syntax* 的语法片段: 10 | 11 | | 符号 | 示例 | 释义 | 12 | |-------------------|-------------------------------|-------------------------------| 13 | | CAPITAL | KW_IF, INTEGER_LITERAL | 词法相关记号(符号)待修正 | 14 | | _ItalicCamelCase_ | _LetStatement_, _Item_ | 语法相关定义 待修正 | 15 | | `string` | `x`, `while`, `*` | 字符(串) | 16 | | \\x | \\n, \\r, \\t, \\0 | 转义字符 | 17 | | x? | `pub`? | 可选项 | 18 | | x\* | _OuterAttribute_\* | x 零次或多次重复 | 19 | | x+ | _MacroMatch_+ | x 一次或多次重复 | 20 | | xa..b | HEX_DIGIT1..6 | x 在 a -> b 范围内重复 | 21 | | \| | `u8` \| `u16`, Block \| Item | 或 | 22 | | [ ] | [`b` `B`] | 列举的任意字符 | 23 | | [ - ] | [`a`-`z`] | a -> z 范围内的任意字符 | 24 | | ~[ ] | ~[`b` `B`] | 除列举范围外的任意字符 | 25 | | ~`string` | ~`\n`, ~`*/` | 除此字符序列外的任意字符 | 26 | | ( ) | (`,` _Parameter_)? | 分组项 待修正 | 27 | 28 | ## 字符串表组合 29 | 30 | 语法中的一些规则—尤其是[单目运算符][unary operators],[双目运算符][binary 31 | operators]和[关键字][keywords]—以一种简单的形式表现:可打印的字符串表。这些规则是[记号][tokens]相关规则的子集,并且被假定为词法分析阶段的结果。该阶段由一个 DFA(Deterministic Finite 32 | Automaton,确定有限状态自动机)驱动,通过分离所有这些字符串表入口执行。 33 | 34 | 当语法中出现如 `monospace` 这样的字符串时(译者注:半角双引号 `"` 中的字符串),它是对字符串表组合中的单个成员的隐式引用。查阅[记号][tokens]以获取更多信息。 35 | 36 | [binary operators]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators 37 | [keywords]: keywords.md 38 | [tokens]: tokens.md 39 | [unary operators]: expressions/operator-expr.md#borrow-operators 40 | -------------------------------------------------------------------------------- /src/runtime.md: -------------------------------------------------------------------------------- 1 | # The Rust runtime 2 | 3 | This section documents features that define some aspects of the Rust runtime. 4 | 5 | ## The `panic_handler` attribute 6 | 7 | The *`panic_handler` attribute* can only be applied to a function with signature 8 | `fn(&PanicInfo) -> !`. The function marked with this [attribute] defines the behavior of panics. The 9 | [`PanicInfo`] struct contains information about the location of the panic. There must be a single 10 | `panic_handler` function in the dependency graph of a binary, dylib or cdylib crate. 11 | 12 | Below is shown a `panic_handler` function that logs the panic message and then halts the 13 | thread. 14 | 15 | 16 | ```rust,ignore 17 | #![no_std] 18 | 19 | use core::fmt::{self, Write}; 20 | use core::panic::PanicInfo; 21 | 22 | struct Sink { 23 | // .. 24 | # _0: (), 25 | } 26 | # 27 | # impl Sink { 28 | # fn new() -> Sink { Sink { _0: () }} 29 | # } 30 | # 31 | # impl fmt::Write for Sink { 32 | # fn write_str(&mut self, _: &str) -> fmt::Result { Ok(()) } 33 | # } 34 | 35 | #[panic_handler] 36 | fn panic(info: &PanicInfo) -> ! { 37 | let mut sink = Sink::new(); 38 | 39 | // logs "panicked at '$reason', src/main.rs:27:4" to some `sink` 40 | let _ = writeln!(sink, "{}", info); 41 | 42 | loop {} 43 | } 44 | ``` 45 | 46 | ### Standard behavior 47 | 48 | The standard library provides an implementation of `panic_handler` that 49 | defaults to unwinding the stack but that can be [changed to abort the 50 | process][abort]. The standard library's panic behavior can be modified at 51 | runtime with the [set_hook] function. 52 | 53 | ## The `global_allocator` attribute 54 | 55 | The *`global_allocator` attribute* is used on a [static item] implementing the 56 | [`GlobalAlloc`] trait to set the global allocator. 57 | 58 | ## The `windows_subsystem` attribute 59 | 60 | The *`windows_subsystem` attribute* may be applied at the crate level to set 61 | the [subsystem] when linking on a Windows target. It uses the 62 | [_MetaNameValueStr_] syntax to specify the subsystem with a value of either 63 | `console` or `windows`. This attribute is ignored on non-Windows targets, and 64 | for non-`bin` [crate types]. 65 | 66 | ```rust 67 | #![windows_subsystem = "windows"] 68 | ``` 69 | 70 | [_MetaNameValueStr_]: attributes.md#meta-item-attribute-syntax 71 | [`GlobalAlloc`]: ../alloc/alloc/trait.GlobalAlloc.html 72 | [`PanicInfo`]: ../core/panic/struct.PanicInfo.html 73 | [abort]: ../book/ch09-01-unrecoverable-errors-with-panic.html 74 | [attribute]: attributes.md 75 | [crate types]: linkage.md 76 | [set_hook]: ../std/panic/fn.set_hook.html 77 | [static item]: items/static-items.md 78 | [subsystem]: https://msdn.microsoft.com/en-us/library/fcc1zstk.aspx 79 | -------------------------------------------------------------------------------- /src/statements-and-expressions.md: -------------------------------------------------------------------------------- 1 | # Statements and expressions 2 | 3 | Rust is _primarily_ an expression language. This means that most forms of 4 | value-producing or effect-causing evaluation are directed by the uniform syntax 5 | category of _expressions_. Each kind of expression can typically _nest_ within 6 | each other kind of expression, and rules for evaluation of expressions involve 7 | specifying both the value produced by the expression and the order in which its 8 | sub-expressions are themselves evaluated. 9 | 10 | In contrast, statements in Rust serve _mostly_ to contain and explicitly 11 | sequence expression evaluation. 12 | -------------------------------------------------------------------------------- /src/statements.md: -------------------------------------------------------------------------------- 1 | # Statements 2 | 3 | > **Syntax**\ 4 | > _Statement_ :\ 5 | >       `;`\ 6 | >    | [_Item_]\ 7 | >    | [_LetStatement_]\ 8 | >    | [_ExpressionStatement_]\ 9 | >    | [_MacroInvocationSemi_] 10 | 11 | 12 | A *statement* is a component of a [block], which is in turn a component of an 13 | outer [expression] or [function]. 14 | 15 | Rust has two kinds of statement: [declaration 16 | statements](#declaration-statements) and [expression 17 | statements](#expression-statements). 18 | 19 | ## Declaration statements 20 | 21 | A *declaration statement* is one that introduces one or more *names* into the 22 | enclosing statement block. The declared names may denote new variables or new 23 | [items][item]. 24 | 25 | The two kinds of declaration statements are item declarations and `let` 26 | statements. 27 | 28 | ### Item declarations 29 | 30 | An *item declaration statement* has a syntactic form identical to an 31 | [item declaration][item] within a [module]. Declaring an item within a statement 32 | block restricts its scope to the block containing the statement. The item is not 33 | given a [canonical path] nor are any sub-items it may declare. The exception to 34 | this is that associated items defined by [implementations] are still accessible 35 | in outer scopes as long as the item and, if applicable, trait are accessible. 36 | It is otherwise identical in meaning to declaring the item inside a module. 37 | 38 | There is no implicit capture of the containing function's generic parameters, 39 | parameters, and local variables. For example, `inner` may not access 40 | `outer_var`. 41 | 42 | ```rust 43 | fn outer() { 44 | let outer_var = true; 45 | 46 | fn inner() { /* outer_var is not in scope here */ } 47 | 48 | inner(); 49 | } 50 | ``` 51 | 52 | ### `let` statements 53 | 54 | > **Syntax**\ 55 | > _LetStatement_ :\ 56 | >    [_OuterAttribute_]\* `let` [_Pattern_] 57 | > ( `:` [_Type_] )? (`=` [_Expression_] )? `;` 58 | 59 | A *`let` statement* introduces a new set of [variables], given by an 60 | irrefutable [pattern]. The pattern is followed optionally by a type 61 | annotation and then optionally by an initializer expression. When no 62 | type annotation is given, the compiler will infer the type, or signal 63 | an error if insufficient type information is available for definite 64 | inference. Any variables introduced by a variable declaration are visible 65 | from the point of declaration until the end of the enclosing block scope. 66 | 67 | ## Expression statements 68 | 69 | > **Syntax**\ 70 | > _ExpressionStatement_ :\ 71 | >       [_ExpressionWithoutBlock_][expression] `;`\ 72 | >    | [_ExpressionWithBlock_][expression] `;`? 73 | 74 | An *expression statement* is one that evaluates an [expression] and ignores its 75 | result. As a rule, an expression statement's purpose is to trigger the effects 76 | of evaluating its expression. 77 | 78 | An expression that consists of only a [block expression][block] or control flow 79 | expression, if used in a context where a statement is permitted, can omit the 80 | trailing semicolon. This can cause an ambiguity between it being parsed as a 81 | standalone statement and as a part of another expression; in this case, it is 82 | parsed as a statement. The type of [_ExpressionWithBlock_][expression] 83 | expressions when used as statements must be the unit type. 84 | 85 | ```rust 86 | # let mut v = vec![1, 2, 3]; 87 | v.pop(); // Ignore the element returned from pop 88 | if v.is_empty() { 89 | v.push(5); 90 | } else { 91 | v.remove(0); 92 | } // Semicolon can be omitted. 93 | [1]; // Separate expression statement, not an indexing expression. 94 | ``` 95 | 96 | When the trailing semicolon is omitted, the result must be type `()`. 97 | 98 | ```rust 99 | // bad: the block's type is i32, not () 100 | // Error: expected `()` because of default return type 101 | // if true { 102 | // 1 103 | // } 104 | 105 | // good: the block's type is i32 106 | if true { 107 | 1 108 | } else { 109 | 2 110 | }; 111 | ``` 112 | 113 | ## Attributes on Statements 114 | 115 | Statements accept [outer attributes]. The attributes that have meaning on a 116 | statement are [`cfg`], and [the lint check attributes]. 117 | 118 | [block]: expressions/block-expr.md 119 | [expression]: expressions.md 120 | [function]: items/functions.md 121 | [item]: items.md 122 | [module]: items/modules.md 123 | [canonical path]: paths.md#canonical-paths 124 | [implementations]: items/implementations.md 125 | [variables]: variables.md 126 | [outer attributes]: attributes.md 127 | [`cfg`]: conditional-compilation.md 128 | [the lint check attributes]: attributes/diagnostics.md#lint-check-attributes 129 | [pattern]: patterns.md 130 | [_ExpressionStatement_]: #expression-statements 131 | [_Expression_]: expressions.md 132 | [_Item_]: items.md 133 | [_LetStatement_]: #let-statements 134 | [_MacroInvocationSemi_]: macros.md#macro-invocation 135 | [_OuterAttribute_]: attributes.md 136 | [_Pattern_]: patterns.md 137 | [_Type_]: types.md 138 | -------------------------------------------------------------------------------- /src/subtyping.md: -------------------------------------------------------------------------------- 1 | # Subtyping and Variance 2 | 3 | Subtyping is implicit and can occur at any stage in type checking or 4 | inference. Subtyping in Rust is very restricted and occurs only due to 5 | variance with respect to lifetimes and between types with higher ranked 6 | lifetimes. If we were to erase lifetimes from types, then the only subtyping 7 | would be due to type equality. 8 | 9 | Consider the following example: string literals always have `'static` 10 | lifetime. Nevertheless, we can assign `s` to `t`: 11 | 12 | ```rust 13 | fn bar<'a>() { 14 | let s: &'static str = "hi"; 15 | let t: &'a str = s; 16 | } 17 | ``` 18 | 19 | Since `'static` outlives the lifetime parameter `'a`, `&'static str` is a 20 | subtype of `&'a str`. 21 | 22 | [Higher-ranked] [function pointers] and [trait objects] have another 23 | subtype relation. They are subtypes of types that are given by substitutions of 24 | the higher-ranked lifetimes. Some examples: 25 | 26 | ```rust 27 | // Here 'a is substituted for 'static 28 | let subtype: &(for<'a> fn(&'a i32) -> &'a i32) = &((|x| x) as fn(&_) -> &_); 29 | let supertype: &(fn(&'static i32) -> &'static i32) = subtype; 30 | 31 | // This works similarly for trait objects 32 | let subtype: &(for<'a> Fn(&'a i32) -> &'a i32) = &|x| x; 33 | let supertype: &(Fn(&'static i32) -> &'static i32) = subtype; 34 | 35 | // We can also substitute one higher-ranked lifetime for another 36 | let subtype: &(for<'a, 'b> fn(&'a i32, &'b i32))= &((|x, y| {}) as fn(&_, &_)); 37 | let supertype: &for<'c> fn(&'c i32, &'c i32) = subtype; 38 | ``` 39 | 40 | ## Variance 41 | 42 | Variance is a property that generic types have with respect to their arguments. 43 | A generic type's *variance* in a parameter is how the subtyping of the 44 | parameter affects the subtyping of the type. 45 | 46 | * `F` is *covariant* over `T` if `T` being a subtype of `U` implies that 47 | `F` is a subtype of `F` (subtyping "passes through") 48 | * `F` is *contravariant* over `T` if `T` being a subtype of `U` implies that 49 | `F` is a subtype of `F` 50 | * `F` is *invariant* over `T` otherwise (no subtyping relation can be 51 | derived) 52 | 53 | Variance of types is automatically determined as follows 54 | 55 | | Type | Variance in `'a` | Variance in `T` | 56 | |-------------------------------|-------------------|-------------------| 57 | | `&'a T` | covariant | covariant | 58 | | `&'a mut T` | covariant | invariant | 59 | | `*const T` | | covariant | 60 | | `*mut T` | | invariant | 61 | | `[T]` and `[T; n]` | | covariant | 62 | | `fn() -> T` | | covariant | 63 | | `fn(T) -> ()` | | contravariant | 64 | | `std::cell::UnsafeCell` | | invariant | 65 | | `std::marker::PhantomData` | | covariant | 66 | | `Trait + 'a` | covariant | invariant | 67 | 68 | The variance of other `struct`, `enum`, `union`, and tuple types is decided by 69 | looking at the variance of the types of their fields. If the parameter is used 70 | in positions with different variances then the parameter is invariant. For 71 | example the following struct is covariant in `'a` and `T` and invariant in `'b` 72 | and `U`. 73 | 74 | ```rust 75 | use std::cell::UnsafeCell; 76 | struct Variance<'a, 'b, T, U: 'a> { 77 | x: &'a U, // This makes `Variance` covariant in 'a, and would 78 | // make it covariant in U, but U is used later 79 | y: *const T, // Covariant in T 80 | z: UnsafeCell<&'b f64>, // Invariant in 'b 81 | w: *mut U, // Invariant in U, makes the whole struct invariant 82 | } 83 | ``` 84 | 85 | [function pointers]: types/function-pointer.md 86 | [Higher-ranked]: ../nomicon/hrtb.html 87 | [trait objects]: types/trait-object.md 88 | -------------------------------------------------------------------------------- /src/trait-bounds.md: -------------------------------------------------------------------------------- 1 | # Trait and lifetime bounds 2 | 3 | > **Syntax**\ 4 | > _TypeParamBounds_ :\ 5 | >    _TypeParamBound_ ( `+` _TypeParamBound_ )\* `+`? 6 | > 7 | > _TypeParamBound_ :\ 8 | >       _Lifetime_ | _TraitBound_ 9 | > 10 | > _TraitBound_ :\ 11 | >       `?`? 12 | > [_ForLifetimes_](#higher-ranked-trait-bounds)? [_TypePath_]\ 13 | >    | `(` `?`? 14 | > [_ForLifetimes_](#higher-ranked-trait-bounds)? [_TypePath_] `)` 15 | > 16 | > _LifetimeBounds_ :\ 17 | >    ( _Lifetime_ `+` )\* _Lifetime_? 18 | > 19 | > _Lifetime_ :\ 20 | >       [LIFETIME_OR_LABEL]\ 21 | >    | `'static`\ 22 | >    | `'_` 23 | 24 | [Trait] and lifetime bounds provide a way for [generic items][generic] to 25 | restrict which types and lifetimes are used as their parameters. Bounds can be 26 | provided on any type in a [where clause]. There are also shorter forms for 27 | certain common cases: 28 | 29 | * Bounds written after declaring a [generic parameter][generic]: 30 | `fn f() {}` is the same as `fn f where A: Copy () {}`. 31 | * In trait declarations as [supertraits]: `trait Circle : Shape {}` is 32 | equivalent to `trait Circle where Self : Shape {}`. 33 | * In trait declarations as bounds on [associated types]: 34 | `trait A { type B: Copy; }` is equivalent to 35 | `trait A where Self::B: Copy { type B; }`. 36 | 37 | Bounds on an item must be satisfied when using the item. When type checking and 38 | borrow checking a generic item, the bounds can be used to determine that a 39 | trait is implemented for a type. For example, given `Ty: Trait` 40 | 41 | * In the body of a generic function, methods from `Trait` can be called on `Ty` 42 | values. Likewise associated constants on the `Trait` can be used. 43 | * Associated types from `Trait` can be used. 44 | * Generic functions and types with a `T: Trait` bounds can be used with `Ty` 45 | being used for `T`. 46 | 47 | ```rust 48 | # type Surface = i32; 49 | trait Shape { 50 | fn draw(&self, Surface); 51 | fn name() -> &'static str; 52 | } 53 | 54 | fn draw_twice(surface: Surface, sh: T) { 55 | sh.draw(surface); // Can call method because T: Shape 56 | sh.draw(surface); 57 | } 58 | 59 | fn copy_and_draw_twice(surface: Surface, sh: T) where T: Shape { 60 | let shape_copy = sh; // doesn't move sh because T: Copy 61 | draw_twice(surface, sh); // Can use generic function because T: Shape 62 | } 63 | 64 | struct Figure(S, S); 65 | 66 | fn name_figure( 67 | figure: Figure, // Type Figure is well-formed because U: Shape 68 | ) { 69 | println!( 70 | "Figure of two {}", 71 | U::name(), // Can use associated function 72 | ); 73 | } 74 | ``` 75 | 76 | Trait and lifetime bounds are also used to name [trait objects]. 77 | 78 | ## `?Sized` 79 | 80 | `?` is only used to declare that the [`Sized`] trait may not be 81 | implemented for a type parameter or associated type. `?Sized` may 82 | not be used as a bound for other types. 83 | 84 | ## Lifetime bounds 85 | 86 | Lifetime bounds can be applied to types or other lifetimes. The bound `'a: 'b` 87 | is usually read as `'a` *outlives* `'b`. `'a: 'b` means that `'a` lasts longer 88 | than `'b`, so a reference `&'a ()` is valid whenever `&'b ()` is valid. 89 | 90 | ```rust 91 | fn f<'a, 'b>(x: &'a i32, mut y: &'b i32) where 'a: 'b { 92 | y = x; // &'a i32 is a subtype of &'b i32 because 'a: 'b 93 | let r: &'b &'a i32 = &&0; // &'b &'a i32 is well formed because 'a: 'b 94 | } 95 | ``` 96 | 97 | `T: 'a` means that all lifetime parameters of `T` outlive `'a`. For example if 98 | `'a` is an unconstrained lifetime parameter then `i32: 'static` and 99 | `&'static str: 'a` are satisfied but `Vec<&'a ()>: 'static` is not. 100 | 101 | ## Higher-ranked trait bounds 102 | 103 | Type bounds may be *higher ranked* over lifetimes. These bounds specify a bound 104 | is true *for all* lifetimes. For example, a bound such as `for<'a> &'a T: 105 | PartialEq` would require an implementation like 106 | 107 | ```rust 108 | # struct T; 109 | impl<'a> PartialEq for &'a T { 110 | // ... 111 | # fn eq(&self, other: &i32) -> bool {true} 112 | } 113 | ``` 114 | 115 | and could then be used to compare a `&'a T` with any lifetime to an `i32`. 116 | 117 | Only a higher-ranked bound can be used here as the lifetime of the reference is 118 | shorter than a lifetime parameter on the function: 119 | 120 | ```rust 121 | fn call_on_ref_zero(f: F) where for<'a> F: Fn(&'a i32) { 122 | let zero = 0; 123 | f(&zero); 124 | } 125 | ``` 126 | 127 | Higher-ranked lifetimes may also be specified just before the trait, the only 128 | difference is the scope of the lifetime parameter, which extends only to the 129 | end of the following trait instead of the whole bound. This function is 130 | equivalent to the last one. 131 | 132 | ```rust 133 | fn call_on_ref_zero(f: F) where F: for<'a> Fn(&'a i32) { 134 | let zero = 0; 135 | f(&zero); 136 | } 137 | ``` 138 | 139 | [LIFETIME_OR_LABEL]: tokens.md#lifetimes-and-loop-labels 140 | [_TypePath_]: paths.md#paths-in-types 141 | [`Sized`]: special-types-and-traits.md#sized 142 | 143 | [associated types]: items/associated-items.md#associated-types 144 | [supertraits]: items/traits.md#supertraits 145 | [generic]: items/generics.md 146 | [Trait]: items/traits.md#trait-bounds 147 | [trait objects]: types/trait-object.md 148 | [where clause]: items/generics.md#where-clauses 149 | -------------------------------------------------------------------------------- /src/type-system.md: -------------------------------------------------------------------------------- 1 | # Type system 2 | -------------------------------------------------------------------------------- /src/types-redirect.html: -------------------------------------------------------------------------------- 1 | 44 | -------------------------------------------------------------------------------- /src/types/array.md: -------------------------------------------------------------------------------- 1 | # Array types 2 | 3 | > **Syntax**\ 4 | > _ArrayType_ :\ 5 | >    `[` [_Type_] `;` [_Expression_] `]` 6 | 7 | An array is a fixed-size sequence of `N` elements of type `T`. The array type 8 | is written as `[T; N]`. The size is an expression that evaluates to a 9 | [`usize`]. 10 | 11 | Examples: 12 | 13 | ```rust 14 | // A stack-allocated array 15 | let array: [i32; 3] = [1, 2, 3]; 16 | 17 | // A heap-allocated array, coerced to a slice 18 | let boxed_array: Box<[i32]> = Box::new([1, 2, 3]); 19 | ``` 20 | 21 | All elements of arrays are always initialized, and access to an array is 22 | always bounds-checked in safe methods and operators. 23 | 24 | > Note: The [`Vec`] standard library type provides a heap-allocated resizable 25 | > array type. 26 | 27 | [_Expression_]: ../expressions.md 28 | [_Type_]: ../types.md#type-expressions 29 | [`Vec`]: ../../std/vec/struct.Vec.html 30 | [`usize`]: numeric.md#machine-dependent-integer-types 31 | -------------------------------------------------------------------------------- /src/types/boolean.md: -------------------------------------------------------------------------------- 1 | # Boolean type 2 | 3 | The `bool` type is a datatype which can be either `true` or `false`. The boolean 4 | type uses one byte of memory. It is used in comparisons and bitwise operations 5 | like `&`, `|`, and `!`. 6 | 7 | ```rust 8 | fn main() { 9 | let x = true; 10 | let y: bool = false; // with the boolean type annotation 11 | 12 | // Use of booleans in conditional expressions 13 | if x { 14 | println!("x is true"); 15 | } 16 | } 17 | ``` 18 | -------------------------------------------------------------------------------- /src/types/enum.md: -------------------------------------------------------------------------------- 1 | # Enumerated types 2 | 3 | An *enumerated type* is a nominal, heterogeneous disjoint union type, denoted 4 | by the name of an [`enum` item]. [^enumtype] 5 | 6 | An [`enum` item] declares both the type and a number of *variants*, each of 7 | which is independently named and has the syntax of a struct, tuple struct or 8 | unit-like struct. 9 | 10 | New instances of an `enum` can be constructed in an [enumeration variant 11 | expression]. 12 | 13 | Any `enum` value consumes as much memory as the largest variant for its 14 | corresponding `enum` type, as well as the size needed to store a discriminant. 15 | 16 | Enum types cannot be denoted *structurally* as types, but must be denoted by 17 | named reference to an [`enum` item]. 18 | 19 | [^enumtype]: ../The `enum` type is analogous to a `data` constructor declaration in 20 | ML, or a *pick ADT* in Limbo. 21 | 22 | [`enum` item]: ../items/enumerations.md 23 | [enumeration variant expression]: ../expressions/enum-variant-expr.md 24 | -------------------------------------------------------------------------------- /src/types/function-item.md: -------------------------------------------------------------------------------- 1 | # Function item types 2 | 3 | When referred to, a function item, or the constructor of a tuple-like struct or 4 | enum variant, yields a zero-sized value of its _function item type_. That type 5 | explicitly identifies the function - its name, its type arguments, and its 6 | early-bound lifetime arguments (but not its late-bound lifetime arguments, 7 | which are only assigned when the function is called) - so the value does not 8 | need to contain an actual function pointer, and no indirection is needed when 9 | the function is called. 10 | 11 | There is no syntax that directly refers to a function item type, but the 12 | compiler will display the type as something like `fn(u32) -> i32 {fn_name}` in 13 | error messages. 14 | 15 | Because the function item type explicitly identifies the function, the item 16 | types of different functions - different items, or the same item with different 17 | generics - are distinct, and mixing them will create a type error: 18 | 19 | ```rust,compile_fail,E0308 20 | fn foo() { } 21 | let x = &mut foo::; 22 | *x = foo::; //~ ERROR mismatched types 23 | ``` 24 | 25 | However, there is a [coercion] from function items to [function pointers] with 26 | the same signature, which is triggered not only when a function item is used 27 | when a function pointer is directly expected, but also when different function 28 | item types with the same signature meet in different arms of the same `if` or 29 | `match`: 30 | 31 | ```rust 32 | # let want_i32 = false; 33 | # fn foo() { } 34 | 35 | // `foo_ptr_1` has function pointer type `fn()` here 36 | let foo_ptr_1: fn() = foo::; 37 | 38 | // ... and so does `foo_ptr_2` - this type-checks. 39 | let foo_ptr_2 = if want_i32 { 40 | foo:: 41 | } else { 42 | foo:: 43 | }; 44 | ``` 45 | 46 | All function items implement [`Fn`], [`FnMut`], [`FnOnce`], [`Copy`], 47 | [`Clone`], [`Send`], and [`Sync`]. 48 | 49 | [`Clone`]: ../special-types-and-traits.md#clone 50 | [`Copy`]: ../special-types-and-traits.md#copy 51 | [`FnMut`]: ../../std/ops/trait.FnMut.html 52 | [`FnOnce`]: ../../std/ops/trait.FnOnce.html 53 | [`Fn`]: ../../std/ops/trait.Fn.html 54 | [`Send`]: ../special-types-and-traits.md#send 55 | [`Sync`]: ../special-types-and-traits.md#sync 56 | [coercion]: ../type-coercions.md 57 | [function pointers]: function-pointer.md 58 | -------------------------------------------------------------------------------- /src/types/function-pointer.md: -------------------------------------------------------------------------------- 1 | # Function pointer types 2 | 3 | > **Syntax**\ 4 | > _BareFunctionType_ :\ 5 | >    [_ForLifetimes_]? [_FunctionQualifiers_] `fn`\ 6 | >       `(` _FunctionParametersMaybeNamedVariadic_? `)` _BareFunctionReturnType_? 7 | > 8 | > _BareFunctionReturnType_:\ 9 | >    `->` [_TypeNoBounds_] 10 | > 11 | > _FunctionParametersMaybeNamedVariadic_ :\ 12 | >    _MaybeNamedFunctionParameters_ | _MaybeNamedFunctionParametersVariadic_ 13 | > 14 | > _MaybeNamedFunctionParameters_ :\ 15 | >    _MaybeNamedParam_ ( `,` _MaybeNamedParam_ )\* `,`? 16 | > 17 | > _MaybeNamedParam_ :\ 18 | >    [_OuterAttribute_]\* ( ( [IDENTIFIER] | `_` ) `:` )? [_Type_] 19 | > 20 | > _MaybeNamedFunctionParametersVariadic_ :\ 21 | >    ( _MaybeNamedParam_ `,` )\* _MaybeNamedParam_ `,` [_OuterAttribute_]\* `...` 22 | 23 | Function pointer types, written using the `fn` keyword, refer to a function 24 | whose identity is not necessarily known at compile-time. They can be created 25 | via a coercion from both [function items] and non-capturing [closures]. 26 | 27 | The `unsafe` qualifier indicates that the type's value is an [unsafe 28 | function], and the `extern` qualifier indicates it is an [extern function]. 29 | 30 | Variadic parameters can only be specified with [`extern`] function types with 31 | the `"C"` or `"cdecl"` calling convention. 32 | 33 | An example where `Binop` is defined as a function pointer type: 34 | 35 | ```rust 36 | fn add(x: i32, y: i32) -> i32 { 37 | x + y 38 | } 39 | 40 | let mut x = add(5,7); 41 | 42 | type Binop = fn(i32, i32) -> i32; 43 | let bo: Binop = add; 44 | x = bo(5,7); 45 | ``` 46 | 47 | ## Attributes on function pointer parameters 48 | 49 | Attributes on function pointer parameters follow the same rules and 50 | restrictions as [regular function parameters]. 51 | 52 | [IDENTIFIER]: ../identifiers.md 53 | [_ForLifetimes_]: ../items/generics.md#where-clauses 54 | [_FunctionQualifiers_]: ../items/functions.md 55 | [_TypeNoBounds_]: ../types.md#type-expressions 56 | [_Type_]: ../types.md#type-expressions 57 | [_OuterAttribute_]: ../attributes.md 58 | [`extern`]: ../items/external-blocks.md 59 | [closures]: closure.md 60 | [extern function]: ../items/functions.md#extern-function-qualifier 61 | [function items]: function-item.md 62 | [unsafe function]: ../unsafe-functions.md 63 | [regular function parameters]: ../items/functions.md#attributes-on-function-parameters -------------------------------------------------------------------------------- /src/types/impl-trait.md: -------------------------------------------------------------------------------- 1 | # Impl trait 2 | 3 | > **Syntax**\ 4 | > _ImplTraitType_ : `impl` [_TypeParamBounds_] 5 | > 6 | > _ImplTraitTypeOneBound_ : `impl` [_TraitBound_] 7 | 8 | ## Anonymous type parameters 9 | 10 | > Note: This section is a placeholder for more comprehensive reference 11 | > material. 12 | 13 | > Note: This is often called "impl Trait in argument position". 14 | 15 | Functions can declare an argument to be an anonymous type parameter where the 16 | callee must provide a type that has the bounds declared by the anonymous type 17 | parameter and the function can only use the methods available by the trait 18 | bounds of the anonymous type parameter. 19 | 20 | They are written as `impl` followed by a set of trait bounds. 21 | 22 | ## Abstract return types 23 | 24 | > Note: This section is a placeholder for more comprehensive reference 25 | > material. 26 | 27 | > Note: This is often called "impl Trait in return position". 28 | 29 | Functions, except for associated trait functions, can return an abstract 30 | return type. These types stand in for another concrete type where the 31 | use-site may only use the trait methods declared by the trait bounds of the 32 | type. 33 | 34 | They are written as `impl` followed by a set of trait bounds. 35 | 36 | [_TraitBound_]: ../trait-bounds.md 37 | [_TypeParamBounds_]: ../trait-bounds.md 38 | -------------------------------------------------------------------------------- /src/types/inferred.md: -------------------------------------------------------------------------------- 1 | # Inferred type 2 | 3 | > **Syntax**\ 4 | > _InferredType_ : `_` 5 | 6 | The inferred type asks the compiler to infer the type if possible based on the 7 | surrounding information available. It cannot be used in item signatures. It is 8 | often used in generic arguments: 9 | 10 | ```rust 11 | let x: Vec<_> = (0..10).collect(); 12 | ``` 13 | 14 | 19 | -------------------------------------------------------------------------------- /src/types/never.md: -------------------------------------------------------------------------------- 1 | # Never type 2 | 3 | > **Syntax**\ 4 | > _NeverType_ : `!` 5 | 6 | The never type `!` is a type with no values, representing the result of 7 | computations that never complete. Expressions of type `!` can be coerced into 8 | any other type. 9 | 10 | ```rust,should_panic 11 | #![feature(never_type)] 12 | let x: ! = panic!(); 13 | // Can be coerced into any type. 14 | let y: u32 = x; 15 | ``` 16 | 17 | **NB.** The never type was expected to be stabilized in 1.41, but due 18 | to some last minute regressions detected the stabilization was 19 | temporarily reverted. The `!` type can only appear in function return 20 | types presently. See [the tracking 21 | issue](https://github.com/rust-lang/rust/issues/35121) for more 22 | details. 23 | -------------------------------------------------------------------------------- /src/types/numeric.md: -------------------------------------------------------------------------------- 1 | # Numeric types 2 | 3 | ## Integer types 4 | 5 | The unsigned integer types consist of: 6 | 7 | Type | Minimum | Maximum 8 | -------|---------|------------------- 9 | `u8` | 0 | 28-1 10 | `u16` | 0 | 216-1 11 | `u32` | 0 | 232-1 12 | `u64` | 0 | 264-1 13 | `u128` | 0 | 2128-1 14 | 15 | The signed two's complement integer types consist of: 16 | 17 | Type | Minimum | Maximum 18 | -------|--------------------|------------------- 19 | `i8` | -(27) | 27-1 20 | `i16` | -(215) | 215-1 21 | `i32` | -(231) | 231-1 22 | `i64` | -(263) | 263-1 23 | `i128` | -(2127) | 2127-1 24 | 25 | 26 | ## Floating-point types 27 | 28 | The IEEE 754-2008 "binary32" and "binary64" floating-point types are `f32` and 29 | `f64`, respectively. 30 | 31 | ## Machine-dependent integer types 32 | 33 | The `usize` type is an unsigned integer type with the same number of bits as the 34 | platform's pointer type. It can represent every memory address in the process. 35 | 36 | The `isize` type is a signed integer type with the same number of bits as the 37 | platform's pointer type. The theoretical upper bound on object and array size 38 | is the maximum `isize` value. This ensures that `isize` can be used to calculate 39 | differences between pointers into an object or array and can address every byte 40 | within an object along with one byte past the end. 41 | -------------------------------------------------------------------------------- /src/types/parameters.md: -------------------------------------------------------------------------------- 1 | # Type parameters 2 | 3 | Within the body of an item that has type parameter declarations, the names of 4 | its type parameters are types: 5 | 6 | ```rust 7 | fn to_vec(xs: &[A]) -> Vec { 8 | if xs.is_empty() { 9 | return vec![]; 10 | } 11 | let first: A = xs[0].clone(); 12 | let mut rest: Vec = to_vec(&xs[1..]); 13 | rest.insert(0, first); 14 | rest 15 | } 16 | ``` 17 | 18 | Here, `first` has type `A`, referring to `to_vec`'s `A` type parameter; and 19 | `rest` has type `Vec`, a vector with element type `A`. 20 | -------------------------------------------------------------------------------- /src/types/pointer.md: -------------------------------------------------------------------------------- 1 | # Pointer types 2 | 3 | All pointers in Rust are explicit first-class values. They can be moved or 4 | copied, stored into data structs, and returned from functions. 5 | 6 | ## References (`&` and `&mut`) 7 | 8 | > **Syntax**\ 9 | > _ReferenceType_ :\ 10 | >    `&` [_Lifetime_]? `mut`? [_TypeNoBounds_] 11 | 12 | ### Shared references (`&`) 13 | 14 | These point to memory _owned by some other value_. When a shared reference to 15 | a value is created it prevents direct mutation of the value. [Interior 16 | mutability] provides an exception for this in certain circumstances. As the 17 | name suggests, any number of shared references to a value may exist. A shared 18 | reference type is written `&type`, or `&'a type` when you need to specify an 19 | explicit lifetime. Copying a reference is a "shallow" operation: it involves 20 | only copying the pointer itself, that is, pointers are `Copy`. Releasing a 21 | reference has no effect on the value it points to, but referencing of a 22 | [temporary value] will keep it alive during the scope of the reference itself. 23 | 24 | ### Mutable references (`&mut`) 25 | 26 | These also point to memory owned by some other value. A mutable reference type 27 | is written `&mut type` or `&'a mut type`. A mutable reference (that hasn't been 28 | borrowed) is the only way to access the value it points to, so is not `Copy`. 29 | 30 | ## Raw pointers (`*const` and `*mut`) 31 | 32 | > **Syntax**\ 33 | > _RawPointerType_ :\ 34 | >    `*` ( `mut` | `const` ) [_TypeNoBounds_] 35 | 36 | Raw pointers are pointers without safety or liveness guarantees. Raw pointers 37 | are written as `*const T` or `*mut T`, for example `*const i32` means a raw 38 | pointer to a 32-bit integer. Copying or dropping a raw pointer has no effect 39 | on the lifecycle of any other value. Dereferencing a raw pointer is an 40 | [`unsafe` operation], this can also be used to convert a raw pointer to a 41 | reference by reborrowing it (`&*` or `&mut *`). Raw pointers are generally 42 | discouraged in Rust code; they exist to support interoperability with foreign 43 | code, and writing performance-critical or low-level functions. 44 | 45 | When comparing raw pointers they are compared by their address, rather than by 46 | what they point to. When comparing raw pointers to [dynamically sized types] they 47 | also have their additional data compared. 48 | 49 | ## Smart Pointers 50 | 51 | The standard library contains additional 'smart pointer' types beyond references 52 | and raw pointers. 53 | 54 | [Interior mutability]: ../interior-mutability.md 55 | [_Lifetime_]: ../trait-bounds.md 56 | [_TypeNoBounds_]: ../types.md#type-expressions 57 | [`unsafe` operation]: ../unsafety.md 58 | [dynamically sized types]: ../dynamically-sized-types.md 59 | [temporary value]: ../expressions.md#temporary-lifetimes 60 | -------------------------------------------------------------------------------- /src/types/slice.md: -------------------------------------------------------------------------------- 1 | # Slice types 2 | 3 | > **Syntax**\ 4 | > _SliceType_ :\ 5 | >    `[` [_Type_] `]` 6 | 7 | A slice is a [dynamically sized type] representing a 'view' into a sequence of 8 | elements of type `T`. The slice type is written as `[T]`. 9 | 10 | To use a slice type it generally has to be used behind a pointer for example 11 | as: 12 | 13 | * `&[T]`, a 'shared slice', often just called a 'slice', it doesn't own the 14 | data it points to, it borrows it. 15 | * `&mut [T]`, a 'mutable slice', mutably borrows the data it points to. 16 | * `Box<[T]>`, a 'boxed slice' 17 | 18 | Examples: 19 | 20 | ```rust 21 | // A heap-allocated array, coerced to a slice 22 | let boxed_array: Box<[i32]> = Box::new([1, 2, 3]); 23 | 24 | // A (shared) slice into an array 25 | let slice: &[i32] = &boxed_array[..]; 26 | ``` 27 | 28 | All elements of slices are always initialized, and access to a slice is always 29 | bounds-checked in safe methods and operators. 30 | 31 | [_Type_]: ../types.md#type-expressions 32 | [dynamically sized type]: ../dynamically-sized-types.md 33 | -------------------------------------------------------------------------------- /src/types/struct.md: -------------------------------------------------------------------------------- 1 | # Struct types 2 | 3 | A `struct` *type* is a heterogeneous product of other types, called the 4 | *fields* of the type.[^structtype] 5 | 6 | New instances of a `struct` can be constructed with a [struct expression]. 7 | 8 | The memory layout of a `struct` is undefined by default to allow for compiler 9 | optimizations like field reordering, but it can be fixed with the 10 | [`repr` attribute]. In either case, fields may be given in any order in a 11 | corresponding struct *expression*; the resulting `struct` value will always 12 | have the same memory layout. 13 | 14 | The fields of a `struct` may be qualified by [visibility modifiers], to allow 15 | access to data in a struct outside a module. 16 | 17 | A _tuple struct_ type is just like a struct type, except that the fields are 18 | anonymous. 19 | 20 | A _unit-like struct_ type is like a struct type, except that it has no fields. 21 | The one value constructed by the associated [struct expression] is the only 22 | value that inhabits such a type. 23 | 24 | [^structtype]: ../`struct` types are analogous to `struct` types in C, the 25 | *record* types of the ML family, or the *struct* types of the Lisp family. 26 | 27 | [`repr` attribute]: ../type-layout.md#representations 28 | [struct expression]: ../expressions/struct-expr.md 29 | [visibility modifiers]: ../visibility-and-privacy.md 30 | -------------------------------------------------------------------------------- /src/types/textual.md: -------------------------------------------------------------------------------- 1 | # Textual types 2 | 3 | The types `char` and `str` hold textual data. 4 | 5 | A value of type `char` is a [Unicode scalar value] (i.e. a code point that 6 | is not a surrogate), represented as a 32-bit unsigned word in the 0x0000 to 7 | 0xD7FF or 0xE000 to 0x10FFFF range. A `[char]` is effectively a UCS-4 / UTF-32 8 | string. 9 | 10 | A value of type `str` is a Unicode string, represented as an array of 8-bit 11 | unsigned bytes holding a sequence of UTF-8 code points. Since `str` is a 12 | [dynamically sized type], it is not a _first-class_ type, but can only be 13 | instantiated through a pointer type, such as `&str`. 14 | 15 | [Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value 16 | [dynamically sized type]: ../dynamically-sized-types.md 17 | -------------------------------------------------------------------------------- /src/types/trait-object.md: -------------------------------------------------------------------------------- 1 | # Trait objects 2 | 3 | > **Syntax**\ 4 | > _TraitObjectType_ :\ 5 | >    `dyn`? [_TypeParamBounds_] 6 | > 7 | > _TraitObjectTypeOneBound_ :\ 8 | >    `dyn`? [_TraitBound_] 9 | 10 | A *trait object* is an opaque value of another type that implements a set of 11 | traits. The set of traits is made up of an [object safe] *base trait* plus any 12 | number of [auto traits]. 13 | 14 | Trait objects implement the base trait, its auto traits, and any [supertraits] 15 | of the base trait. 16 | 17 | Trait objects are written as the optional keyword `dyn` followed by a set of 18 | trait bounds, but with the following restrictions on the trait bounds. All 19 | traits except the first trait must be auto traits, there may not be more than 20 | one lifetime, and opt-out bounds (e.g. `?Sized`) are not allowed. Furthermore, 21 | paths to traits may be parenthesized. 22 | 23 | For example, given a trait `Trait`, the following are all trait objects: 24 | 25 | * `Trait` 26 | * `dyn Trait` 27 | * `dyn Trait + Send` 28 | * `dyn Trait + Send + Sync` 29 | * `dyn Trait + 'static` 30 | * `dyn Trait + Send + 'static` 31 | * `dyn Trait +` 32 | * `dyn 'static + Trait`. 33 | * `dyn (Trait)` 34 | 35 | > **Edition Differences**: In the 2015 edition, if the first bound of the 36 | > trait object is a path that starts with `::`, then the `dyn` will be treated 37 | > as a part of the path. The first path can be put in parenthesis to get 38 | > around this. As such, if you want a trait object with the trait 39 | > `::your_module::Trait`, you should write it as `dyn (::your_module::Trait)`. 40 | > 41 | > Beginning in the 2018 edition, `dyn` is a true keyword and is not allowed in 42 | > paths, so the parentheses are not necessary. 43 | 44 | > Note: For clarity, it is recommended to always use the `dyn` keyword on your 45 | > trait objects unless your codebase supports compiling with Rust 1.26 or lower. 46 | 47 | Two trait object types alias each other if the base traits alias each other and 48 | if the sets of auto traits are the same and the lifetime bounds are the same. 49 | For example, `dyn Trait + Send + UnwindSafe` is the same as 50 | `dyn Trait + Unwindsafe + Send`. 51 | 52 | Due to the opaqueness of which concrete type the value is of, trait objects are 53 | [dynamically sized types]. Like all 54 | DSTs, trait objects are used 55 | behind some type of pointer; for example `&dyn SomeTrait` or 56 | `Box`. Each instance of a pointer to a trait object includes: 57 | 58 | - a pointer to an instance of a type `T` that implements `SomeTrait` 59 | - a _virtual method table_, often just called a _vtable_, which contains, for 60 | each method of `SomeTrait` and its [supertraits] that `T` implements, a 61 | pointer to `T`'s implementation (i.e. a function pointer). 62 | 63 | The purpose of trait objects is to permit "late binding" of methods. Calling a 64 | method on a trait object results in virtual dispatch at runtime: that is, a 65 | function pointer is loaded from the trait object vtable and invoked indirectly. 66 | The actual implementation for each vtable entry can vary on an object-by-object 67 | basis. 68 | 69 | An example of a trait object: 70 | 71 | ```rust 72 | trait Printable { 73 | fn stringify(&self) -> String; 74 | } 75 | 76 | impl Printable for i32 { 77 | fn stringify(&self) -> String { self.to_string() } 78 | } 79 | 80 | fn print(a: Box) { 81 | println!("{}", a.stringify()); 82 | } 83 | 84 | fn main() { 85 | print(Box::new(10) as Box); 86 | } 87 | ``` 88 | 89 | In this example, the trait `Printable` occurs as a trait object in both the 90 | type signature of `print`, and the cast expression in `main`. 91 | 92 | ## Trait Object Lifetime Bounds 93 | 94 | Since a trait object can contain references, the lifetimes of those references 95 | need to be expressed as part of the trait object. This lifetime is written as 96 | `Trait + 'a`. There are [defaults] that allow this lifetime to usually be 97 | inferred with a sensible choice. 98 | 99 | [_TraitBound_]: ../trait-bounds.md 100 | [_TypeParamBounds_]: ../trait-bounds.md 101 | [auto traits]: ../special-types-and-traits.md#auto-traits 102 | [defaults]: ../lifetime-elision.md#default-trait-object-lifetimes 103 | [dynamically sized types]: ../dynamically-sized-types.md 104 | [object safe]: ../items/traits.md#object-safety 105 | [supertraits]: ../items/traits.md#supertraits 106 | -------------------------------------------------------------------------------- /src/types/tuple.md: -------------------------------------------------------------------------------- 1 | # Tuple types 2 | 3 | > **Syntax**\ 4 | > _TupleType_ :\ 5 | >       `(` `)`\ 6 | >    | `(` ( [_Type_] `,` )+ [_Type_]? `)` 7 | 8 | A tuple *type* is a heterogeneous product of other types, called the *elements* 9 | of the tuple. It has no nominal name and is instead structurally typed. 10 | 11 | Tuple types and values are denoted by listing the types or values of their 12 | elements, respectively, in a parenthesized, comma-separated list. 13 | 14 | Because tuple elements don't have a name, they can only be accessed by 15 | pattern-matching or by using `N` directly as a field to access the `N`th 16 | element. 17 | 18 | An example of a tuple type and its use: 19 | 20 | ```rust 21 | type Pair<'a> = (i32, &'a str); 22 | let p: Pair<'static> = (10, "ten"); 23 | let (a, b) = p; 24 | 25 | assert_eq!(a, 10); 26 | assert_eq!(b, "ten"); 27 | assert_eq!(p.0, 10); 28 | assert_eq!(p.1, "ten"); 29 | ``` 30 | 31 | For historical reasons and convenience, the tuple type with no elements (`()`) 32 | is often called ‘unit’ or ‘the unit type’. 33 | 34 | [_Type_]: ../types.md#type-expressions 35 | -------------------------------------------------------------------------------- /src/types/union.md: -------------------------------------------------------------------------------- 1 | # Union types 2 | 3 | A *union type* is a nominal, heterogeneous C-like union, denoted by the name of 4 | a [`union` item][item]. 5 | 6 | Unions have no notion of an "active field". Instead, every union access 7 | transmutes parts of the content of the union to the type of the accessed 8 | field. Since transmutes can cause unexpected or undefined behaviour, `unsafe` is 9 | required to read from a union field or to write to a field that doesn't 10 | implement [`Copy`]. See the [item] documentation for further details. 11 | 12 | The memory layout of a `union` is undefined by default, but the `#[repr(...)]` 13 | attribute can be used to fix a layout. 14 | 15 | [`Copy`]: ../special-types-and-traits.md#copy 16 | [item]: ../items/unions.md 17 | -------------------------------------------------------------------------------- /src/unsafe-blocks.md: -------------------------------------------------------------------------------- 1 | # Unsafe blocks 2 | 3 | A block of code can be prefixed with the `unsafe` keyword, to permit calling 4 | `unsafe` functions or dereferencing raw pointers within a safe function. 5 | 6 | When a programmer has sufficient conviction that a sequence of potentially 7 | unsafe operations is actually safe, they can encapsulate that sequence (taken 8 | as a whole) within an `unsafe` block. The compiler will consider uses of such 9 | code safe, in the surrounding context. 10 | 11 | Unsafe blocks are used to wrap foreign libraries, make direct use of hardware 12 | or implement features not directly present in the language. For example, Rust 13 | provides the language features necessary to implement memory-safe concurrency 14 | in the language but the implementation of threads and message passing is in the 15 | standard library. 16 | 17 | Rust's type system is a conservative approximation of the dynamic safety 18 | requirements, so in some cases there is a performance cost to using safe code. 19 | For example, a doubly-linked list is not a tree structure and can only be 20 | represented with reference-counted pointers in safe code. By using `unsafe` 21 | blocks to represent the reverse links as raw pointers, it can be implemented 22 | with only boxes. 23 | -------------------------------------------------------------------------------- /src/unsafe-functions.md: -------------------------------------------------------------------------------- 1 | # Unsafe functions 2 | 3 | Unsafe functions are functions that are not safe in all contexts and/or for all 4 | possible inputs. Such a function must be prefixed with the keyword `unsafe` and 5 | can only be called from an `unsafe` block or another `unsafe` function. 6 | -------------------------------------------------------------------------------- /src/unsafety.md: -------------------------------------------------------------------------------- 1 | # Unsafety 2 | 3 | Unsafe operations are those that can potentially violate the memory-safety 4 | guarantees of Rust's static semantics. 5 | 6 | The following language level features cannot be used in the safe subset of 7 | Rust: 8 | 9 | - Dereferencing a [raw pointer]. 10 | - Reading or writing a [mutable] or [external] static variable. 11 | - Accessing a field of a [`union`], other than to assign to it. 12 | - Calling an unsafe function (including an intrinsic or foreign function). 13 | - Implementing an [unsafe trait]. 14 | 15 | [`union`]: items/unions.md 16 | [mutable]: items/static-items.md#mutable-statics 17 | [external]: items/external-blocks.md 18 | [raw pointer]: types/pointer.md 19 | [unsafe trait]: items/traits.md#unsafe-traits 20 | -------------------------------------------------------------------------------- /src/variables.md: -------------------------------------------------------------------------------- 1 | # Variables 2 | 3 | A _variable_ is a component of a stack frame, either a named function parameter, 4 | an anonymous [temporary](expressions.md#temporary-lifetimes), or a named local 5 | variable. 6 | 7 | A _local variable_ (or *stack-local* allocation) holds a value directly, 8 | allocated within the stack's memory. The value is a part of the stack frame. 9 | 10 | Local variables are immutable unless declared otherwise. For example: 11 | `let mut x = ...`. 12 | 13 | Function parameters are immutable unless declared with `mut`. The `mut` keyword 14 | applies only to the following parameter. For example: `|mut x, y|` and 15 | `fn f(mut x: Box, y: Box)` declare one mutable variable `x` and one 16 | immutable variable `y`. 17 | 18 | Local variables are not initialized when allocated. Instead, the entire frame 19 | worth of local variables are allocated, on frame-entry, in an uninitialized 20 | state. Subsequent statements within a function may or may not initialize the 21 | local variables. Local variables can be used only after they have been 22 | initialized through all reachable control flow paths. 23 | 24 | In this next example, `init_after_if` is initialized after the [`if` expression] 25 | while `uninit_after_if` is not because it is not initialized in the `else` case. 26 | 27 | ```rust 28 | # fn random_bool() -> bool { true } 29 | fn initialization_example() { 30 | let init_after_if: (); 31 | let uninit_after_if: (); 32 | 33 | if random_bool() { 34 | init_after_if = (); 35 | uninit_after_if = (); 36 | } else { 37 | init_after_if = (); 38 | } 39 | 40 | init_after_if; // ok 41 | // uninit_after_if; // err: use of possibly uninitialized `uninit_after_if` 42 | } 43 | ``` 44 | 45 | [`if` expression]: expressions/if-expr.md#if-expressions 46 | -------------------------------------------------------------------------------- /src/whitespace.md: -------------------------------------------------------------------------------- 1 | # 空白 2 | 3 | > [whitespace.md](https://github.com/rust-lang/reference/blob/master/src/whitespace.md) 4 | >
5 | > commit 4a2bdf896cd2df370a91d14cb8ba04e326cd21db 6 | 7 | 空白是任何仅具有 `Pattern_White_Space` Unicode 属性的非空字符串,也就是: 8 | 9 | - `U+0009` (水平制表符,`'\t'`) 10 | - `U+000A` (换行符,`'\n'`) 11 | - `U+000B` (垂直制表符) 12 | - `U+000C` (分页符) 13 | - `U+000D` (回车符,`'\r'`) 14 | - `U+0020` (空格符,`' '`) 15 | - `U+0085` (下移符) 16 | - `U+200E` (自左向右符) 17 | - `U+200F` (自右向左符) 18 | - `U+2028` (行分隔符) 19 | - `U+2029` (段落分隔符) 20 | 21 | Rust 是一个“形式自由”的语言,这意味着任何形式的空白仅用来分隔语法中_记号_,并无语义意义。 22 | 23 | Rust 程序中,如果每个空白元素被替换为任何合法的其它空格元素(如单个空格字符),则它们仍有相同的意义。 24 | -------------------------------------------------------------------------------- /stable-check/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /stable-check/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "stable-check" 5 | version = "0.1.0" 6 | -------------------------------------------------------------------------------- /stable-check/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "stable-check" 3 | version = "0.1.0" 4 | authors = ["steveklabnik "] 5 | edition = "2018" 6 | -------------------------------------------------------------------------------- /stable-check/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::error::Error; 2 | use std::env; 3 | use std::fs; 4 | use std::fs::File; 5 | use std::io::prelude::*; 6 | use std::path::Path; 7 | 8 | fn main() { 9 | let arg = env::args().nth(1).unwrap_or_else(|| { 10 | println!("Please pass a src directory as the first argument"); 11 | std::process::exit(1); 12 | }); 13 | 14 | match check_directory(&Path::new(&arg)) { 15 | Ok(()) => println!("passed!"), 16 | Err(e) => { 17 | println!("Error: {}", e); 18 | std::process::exit(1); 19 | } 20 | } 21 | } 22 | 23 | fn check_directory(dir: &Path) -> Result<(), Box> { 24 | for entry in fs::read_dir(dir)? { 25 | let entry = entry?; 26 | let path = entry.path(); 27 | 28 | if path.is_dir() { 29 | continue; 30 | } 31 | 32 | let mut file = File::open(&path)?; 33 | let mut contents = String::new(); 34 | file.read_to_string(&mut contents)?; 35 | 36 | if contents.contains("#![feature") { 37 | // `attributes.md` contains this and it is legitimate. 38 | if !contents.contains("#![feature(feature1, feature2, feature3)]") { 39 | return Err(From::from(format!("Feature flag found in {:?}", path))); 40 | } 41 | } 42 | } 43 | 44 | Ok(()) 45 | } 46 | -------------------------------------------------------------------------------- /theme/css/general.css: -------------------------------------------------------------------------------- 1 | /* Base styles and content styles */ 2 | 3 | @import 'variables.css'; 4 | 5 | :root { 6 | /* Browser default font-size is 16px, this way 1 rem = 10px */ 7 | font-size: 62.5%; 8 | } 9 | 10 | html { 11 | font-family: "Open Sans", sans-serif; 12 | color: var(--fg); 13 | background-color: var(--bg); 14 | text-size-adjust: none; 15 | } 16 | 17 | body { 18 | margin: 0; 19 | font-size: 1.6rem; 20 | overflow-x: hidden; 21 | } 22 | 23 | code { 24 | font-family: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace !important; 25 | font-size: 0.875em; /* please adjust the ace font size accordingly in editor.js */ 26 | } 27 | 28 | /* Don't change font size in headers. */ 29 | h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { 30 | font-size: unset; 31 | } 32 | 33 | .left { float: left; } 34 | .right { float: right; } 35 | .boring { opacity: 0.6; } 36 | .hide-boring .boring { display: none; } 37 | .hidden { display: none !important; } 38 | 39 | h2, h3 { margin-top: 2.5em; } 40 | h4, h5 { margin-top: 2em; } 41 | 42 | .header + .header h3, 43 | .header + .header h4, 44 | .header + .header h5 { 45 | margin-top: 1em; 46 | } 47 | 48 | h1 a.header:target::before, 49 | h2 a.header:target::before, 50 | h3 a.header:target::before, 51 | h4 a.header:target::before { 52 | display: inline-block; 53 | content: "»"; 54 | margin-left: -30px; 55 | width: 30px; 56 | } 57 | 58 | h1 a.header:target, 59 | h2 a.header:target, 60 | h3 a.header:target, 61 | h4 a.header:target { 62 | scroll-margin-top: calc(var(--menu-bar-height) + 0.5em); 63 | } 64 | 65 | .page { 66 | outline: 0; 67 | padding: 0 var(--page-padding); 68 | margin-top: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */ 69 | } 70 | .page-wrapper { 71 | box-sizing: border-box; 72 | } 73 | .js:not(.sidebar-resizing) .page-wrapper { 74 | transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */ 75 | } 76 | 77 | .content { 78 | overflow-y: auto; 79 | padding: 0 15px; 80 | padding-bottom: 50px; 81 | } 82 | .content main { 83 | margin-left: auto; 84 | margin-right: auto; 85 | max-width: var(--content-max-width); 86 | } 87 | .content p { line-height: 1.45em; } 88 | .content ol { line-height: 1.45em; } 89 | .content ul { line-height: 1.45em; } 90 | .content a { text-decoration: none; } 91 | .content a:hover { text-decoration: underline; } 92 | .content img { max-width: 100%; } 93 | .content .header:link, 94 | .content .header:visited { 95 | color: var(--fg); 96 | } 97 | .content .header:link, 98 | .content .header:visited:hover { 99 | text-decoration: none; 100 | } 101 | 102 | table { 103 | margin: 0 auto; 104 | border-collapse: collapse; 105 | } 106 | table td { 107 | padding: 3px 20px; 108 | border: 1px var(--table-border-color) solid; 109 | } 110 | table thead { 111 | background: var(--table-header-bg); 112 | } 113 | table thead td { 114 | font-weight: 700; 115 | border: none; 116 | } 117 | table thead th { 118 | padding: 3px 20px; 119 | } 120 | table thead tr { 121 | border: 1px var(--table-header-bg) solid; 122 | } 123 | /* Alternate background colors for rows */ 124 | table tbody tr:nth-child(2n) { 125 | background: var(--table-alternate-bg); 126 | } 127 | 128 | 129 | blockquote { 130 | margin: 20px 0; 131 | padding: 0 20px; 132 | color: var(--fg); 133 | background-color: var(--quote-bg); 134 | border-top: .1em solid var(--quote-border); 135 | border-bottom: .1em solid var(--quote-border); 136 | } 137 | 138 | 139 | :not(.footnote-definition) + .footnote-definition, 140 | .footnote-definition + :not(.footnote-definition) { 141 | margin-top: 2em; 142 | } 143 | .footnote-definition { 144 | font-size: 0.9em; 145 | margin: 0.5em 0; 146 | } 147 | .footnote-definition p { 148 | display: inline; 149 | } 150 | 151 | .tooltiptext { 152 | position: absolute; 153 | visibility: hidden; 154 | color: #fff; 155 | background-color: #333; 156 | transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */ 157 | left: -8px; /* Half of the width of the icon */ 158 | top: -35px; 159 | font-size: 0.8em; 160 | text-align: center; 161 | border-radius: 6px; 162 | padding: 5px 8px; 163 | margin: 5px; 164 | z-index: 1000; 165 | } 166 | .tooltipped .tooltiptext { 167 | visibility: visible; 168 | } 169 | 170 | .chapter li.part-title { 171 | color: var(--sidebar-fg); 172 | margin: 5px 0px; 173 | font-weight: bold; 174 | } 175 | -------------------------------------------------------------------------------- /theme/css/print.css: -------------------------------------------------------------------------------- 1 | 2 | #sidebar, 3 | #menu-bar, 4 | .nav-chapters, 5 | .mobile-nav-chapters { 6 | display: none; 7 | } 8 | 9 | #page-wrapper.page-wrapper { 10 | transform: none; 11 | margin-left: 0px; 12 | overflow-y: initial; 13 | } 14 | 15 | #content { 16 | max-width: none; 17 | margin: 0; 18 | padding: 0; 19 | } 20 | 21 | .page { 22 | overflow-y: initial; 23 | } 24 | 25 | code { 26 | background-color: #666666; 27 | border-radius: 5px; 28 | 29 | /* Force background to be printed in Chrome */ 30 | -webkit-print-color-adjust: exact; 31 | } 32 | 33 | pre > .buttons { 34 | z-index: 2; 35 | } 36 | 37 | a, a:visited, a:active, a:hover { 38 | color: #4183c4; 39 | text-decoration: none; 40 | } 41 | 42 | h1, h2, h3, h4, h5, h6 { 43 | page-break-inside: avoid; 44 | page-break-after: avoid; 45 | } 46 | 47 | pre, code { 48 | page-break-inside: avoid; 49 | white-space: pre-wrap; 50 | } 51 | 52 | .fa { 53 | display: none !important; 54 | } 55 | -------------------------------------------------------------------------------- /theme/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzy/rust-reference-zh-cn/02d06fa67b9760580e11f27baa7edf054a264d04/theme/favicon.png -------------------------------------------------------------------------------- /theme/highlight.css: -------------------------------------------------------------------------------- 1 | /* Base16 Atelier Dune Light - Theme */ 2 | /* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) */ 3 | /* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ 4 | 5 | /* Atelier-Dune Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #AAA; 9 | } 10 | 11 | /* Atelier-Dune Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-attribute, 15 | .hljs-tag, 16 | .hljs-name, 17 | .hljs-regexp, 18 | .hljs-link, 19 | .hljs-name, 20 | .hljs-selector-id, 21 | .hljs-selector-class { 22 | color: #d73737; 23 | } 24 | 25 | /* Atelier-Dune Orange */ 26 | .hljs-number, 27 | .hljs-meta, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params { 33 | color: #b65611; 34 | } 35 | 36 | /* Atelier-Dune Green */ 37 | .hljs-string, 38 | .hljs-symbol, 39 | .hljs-bullet { 40 | color: #60ac39; 41 | } 42 | 43 | /* Atelier-Dune Blue */ 44 | .hljs-title, 45 | .hljs-section { 46 | color: #6684e1; 47 | } 48 | 49 | /* Atelier-Dune Purple */ 50 | .hljs-keyword, 51 | .hljs-selector-tag { 52 | color: #b854d4; 53 | } 54 | 55 | .hljs { 56 | display: block; 57 | overflow-x: auto; 58 | background: #f1f1f1; 59 | color: #6e6b5e; 60 | padding: 0.5em; 61 | } 62 | 63 | .hljs-emphasis { 64 | font-style: italic; 65 | } 66 | 67 | .hljs-strong { 68 | font-weight: bold; 69 | } 70 | 71 | .hljs-addition { 72 | color: #22863a; 73 | background-color: #f0fff4; 74 | } 75 | 76 | .hljs-deletion { 77 | color: #b31d28; 78 | background-color: #ffeef0; 79 | } 80 | --------------------------------------------------------------------------------