├── .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 |
![]() Zhang Zhongyu |
50 | ![]() 欢迎您 |
51 | ![]() 欢迎您 |
52 | ![]() 欢迎您 |
53 | ![]() 欢迎您 |
54 | ![]() 欢迎您 |
55 |
` 标签里。
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 | 
Zhang Zhongyu
96 | 
欢迎您
97 | 
欢迎您
98 | 
欢迎您
99 | 
欢迎您
100 | 
欢迎您
101 |
102 |
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 |
--------------------------------------------------------------------------------