feat: added cleanscript
This commit is contained in:
12
appendix/appendix-00.html
Normal file
12
appendix/appendix-00.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Appendix</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="appendix"><a class="header" href="#appendix">Appendix</a></h1>
|
||||
<p>The following sections contain reference material you may find useful in your
|
||||
Rust journey.</p>
|
||||
</body>
|
||||
</html>
|
||||
123
appendix/appendix-01-keywords.html
Normal file
123
appendix/appendix-01-keywords.html
Normal file
@@ -0,0 +1,123 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>A - Keywords</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2 id="appendix-a-keywords"><a class="header" href="#appendix-a-keywords">Appendix A: Keywords</a></h2>
|
||||
<p>The following lists contain keywords that are reserved for current or future
|
||||
use by the Rust language. As such, they cannot be used as identifiers (except
|
||||
as raw identifiers, as we discuss in the <a href="#raw-identifiers">“Raw
|
||||
Identifiers”</a><!-- ignore --> section). <em>Identifiers</em> are names
|
||||
of functions, variables, parameters, struct fields, modules, crates, constants,
|
||||
macros, static values, attributes, types, traits, or lifetimes.</p>
|
||||
<h3 id="keywords-currently-in-use"><a class="header" href="#keywords-currently-in-use">Keywords Currently in Use</a></h3>
|
||||
<p>The following is a list of keywords currently in use, with their functionality
|
||||
described.</p>
|
||||
<ul>
|
||||
<li><strong><code>as</code></strong>: Perform primitive casting, disambiguate the specific trait
|
||||
containing an item, or rename items in <code>use</code> statements.</li>
|
||||
<li><strong><code>async</code></strong>: Return a <code>Future</code> instead of blocking the current thread.</li>
|
||||
<li><strong><code>await</code></strong>: Suspend execution until the result of a <code>Future</code> is ready.</li>
|
||||
<li><strong><code>break</code></strong>: Exit a loop immediately.</li>
|
||||
<li><strong><code>const</code></strong>: Define constant items or constant raw pointers.</li>
|
||||
<li><strong><code>continue</code></strong>: Continue to the next loop iteration.</li>
|
||||
<li><strong><code>crate</code></strong>: In a module path, refers to the crate root.</li>
|
||||
<li><strong><code>dyn</code></strong>: Dynamic dispatch to a trait object.</li>
|
||||
<li><strong><code>else</code></strong>: Fallback for <code>if</code> and <code>if let</code> control flow constructs.</li>
|
||||
<li><strong><code>enum</code></strong>: Define an enumeration.</li>
|
||||
<li><strong><code>extern</code></strong>: Link an external function or variable.</li>
|
||||
<li><strong><code>false</code></strong>: Boolean false literal.</li>
|
||||
<li><strong><code>fn</code></strong>: Define a function or the function pointer type.</li>
|
||||
<li><strong><code>for</code></strong>: Loop over items from an iterator, implement a trait, or specify a
|
||||
higher ranked lifetime.</li>
|
||||
<li><strong><code>if</code></strong>: Branch based on the result of a conditional expression.</li>
|
||||
<li><strong><code>impl</code></strong>: Implement inherent or trait functionality.</li>
|
||||
<li><strong><code>in</code></strong>: Part of <code>for</code> loop syntax.</li>
|
||||
<li><strong><code>let</code></strong>: Bind a variable.</li>
|
||||
<li><strong><code>loop</code></strong>: Loop unconditionally.</li>
|
||||
<li><strong><code>match</code></strong>: Match a value to patterns.</li>
|
||||
<li><strong><code>mod</code></strong>: Define a module.</li>
|
||||
<li><strong><code>move</code></strong>: Make a closure take ownership of all its captures.</li>
|
||||
<li><strong><code>mut</code></strong>: Denote mutability in references, raw pointers, or pattern bindings.</li>
|
||||
<li><strong><code>pub</code></strong>: Denote public visibility in struct fields, <code>impl</code> blocks, or
|
||||
modules.</li>
|
||||
<li><strong><code>ref</code></strong>: Bind by reference.</li>
|
||||
<li><strong><code>return</code></strong>: Return from function.</li>
|
||||
<li><strong><code>Self</code></strong>: A type alias for the type we are defining or implementing.</li>
|
||||
<li><strong><code>self</code></strong>: Method subject or current module.</li>
|
||||
<li><strong><code>static</code></strong>: Global variable or lifetime lasting the entire program
|
||||
execution.</li>
|
||||
<li><strong><code>struct</code></strong>: Define a structure.</li>
|
||||
<li><strong><code>super</code></strong>: Parent module of the current module.</li>
|
||||
<li><strong><code>trait</code></strong>: Define a trait.</li>
|
||||
<li><strong><code>true</code></strong>: Boolean true literal.</li>
|
||||
<li><strong><code>type</code></strong>: Define a type alias or associated type.</li>
|
||||
<li><strong><code>union</code></strong>: Define a <a href="../reference/items/unions.html">union</a><!-- ignore -->; is a keyword only when
|
||||
used in a union declaration.</li>
|
||||
<li><strong><code>unsafe</code></strong>: Denote unsafe code, functions, traits, or implementations.</li>
|
||||
<li><strong><code>use</code></strong>: Bring symbols into scope.</li>
|
||||
<li><strong><code>where</code></strong>: Denote clauses that constrain a type.</li>
|
||||
<li><strong><code>while</code></strong>: Loop conditionally based on the result of an expression.</li>
|
||||
</ul>
|
||||
<h3 id="keywords-reserved-for-future-use"><a class="header" href="#keywords-reserved-for-future-use">Keywords Reserved for Future Use</a></h3>
|
||||
<p>The following keywords do not yet have any functionality but are reserved by
|
||||
Rust for potential future use:</p>
|
||||
<ul>
|
||||
<li><code>abstract</code></li>
|
||||
<li><code>become</code></li>
|
||||
<li><code>box</code></li>
|
||||
<li><code>do</code></li>
|
||||
<li><code>final</code></li>
|
||||
<li><code>gen</code></li>
|
||||
<li><code>macro</code></li>
|
||||
<li><code>override</code></li>
|
||||
<li><code>priv</code></li>
|
||||
<li><code>try</code></li>
|
||||
<li><code>typeof</code></li>
|
||||
<li><code>unsized</code></li>
|
||||
<li><code>virtual</code></li>
|
||||
<li><code>yield</code></li>
|
||||
</ul>
|
||||
<h3 id="raw-identifiers"><a class="header" href="#raw-identifiers">Raw Identifiers</a></h3>
|
||||
<p><em>Raw identifiers</em> are the syntax that lets you use keywords where they wouldn’t
|
||||
normally be allowed. You use a raw identifier by prefixing a keyword with <code>r#</code>.</p>
|
||||
<p>For example, <code>match</code> is a keyword. If you try to compile the following function
|
||||
that uses <code>match</code> as its name:</p>
|
||||
<p><span class="filename">Filename: src/main.rs</span></p>
|
||||
<pre><code class="language-rust ignore does_not_compile">fn match(needle: &str, haystack: &str) -> bool {
|
||||
haystack.contains(needle)
|
||||
}</code></pre>
|
||||
<p>you’ll get this error:</p>
|
||||
<pre><code class="language-text">error: expected identifier, found keyword `match`
|
||||
--> src/main.rs:4:4
|
||||
|
|
||||
4 | fn match(needle: &str, haystack: &str) -> bool {
|
||||
| ^^^^^ expected identifier, found keyword
|
||||
</code></pre>
|
||||
<p>The error shows that you can’t use the keyword <code>match</code> as the function
|
||||
identifier. To use <code>match</code> as a function name, you need to use the raw
|
||||
identifier syntax, like this:</p>
|
||||
<p><span class="filename">Filename: src/main.rs</span></p>
|
||||
<pre class="playground"><code class="language-rust edition2024">fn r#match(needle: &str, haystack: &str) -> bool {
|
||||
haystack.contains(needle)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert!(r#match("foo", "foobar"));
|
||||
}</code></pre>
|
||||
<p>This code will compile without any errors. Note the <code>r#</code> prefix on the function
|
||||
name in its definition as well as where the function is called in <code>main</code>.</p>
|
||||
<p>Raw identifiers allow you to use any word you choose as an identifier, even if
|
||||
that word happens to be a reserved keyword. This gives us more freedom to choose
|
||||
identifier names, as well as lets us integrate with programs written in a
|
||||
language where these words aren’t keywords. In addition, raw identifiers allow
|
||||
you to use libraries written in a different Rust edition than your crate uses.
|
||||
For example, <code>try</code> isn’t a keyword in the 2015 edition but is in the 2018, 2021,
|
||||
and 2024 editions. If you depend on a library that is written using the 2015
|
||||
edition and has a <code>try</code> function, you’ll need to use the raw identifier syntax,
|
||||
<code>r#try</code> in this case, to call that function from your code on later editions.
|
||||
See <a href="appendix-05-editions.html">Appendix E</a><!-- ignore --> for more information on editions.</p>
|
||||
</body>
|
||||
</html>
|
||||
251
appendix/appendix-02-operators.html
Normal file
251
appendix/appendix-02-operators.html
Normal file
@@ -0,0 +1,251 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>B - Operators and Symbols</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2 id="appendix-b-operators-and-symbols"><a class="header" href="#appendix-b-operators-and-symbols">Appendix B: Operators and Symbols</a></h2>
|
||||
<p>This appendix contains a glossary of Rust’s syntax, including operators and
|
||||
other symbols that appear by themselves or in the context of paths, generics,
|
||||
trait bounds, macros, attributes, comments, tuples, and brackets.</p>
|
||||
<h3 id="operators"><a class="header" href="#operators">Operators</a></h3>
|
||||
<p>Table B-1 contains the operators in Rust, an example of how the operator would
|
||||
appear in context, a short explanation, and whether that operator is
|
||||
overloadable. If an operator is overloadable, the relevant trait to use to
|
||||
overload that operator is listed.</p>
|
||||
<p><span class="caption">Table B-1: Operators</span></p>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Operator</th><th>Example</th><th>Explanation</th><th>Overloadable?</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><code>!</code></td><td><code>ident!(...)</code>, <code>ident!{...}</code>, <code>ident![...]</code></td><td>Macro expansion</td><td></td></tr>
|
||||
<tr><td><code>!</code></td><td><code>!expr</code></td><td>Bitwise or logical complement</td><td><code>Not</code></td></tr>
|
||||
<tr><td><code>!=</code></td><td><code>expr != expr</code></td><td>Nonequality comparison</td><td><code>PartialEq</code></td></tr>
|
||||
<tr><td><code>%</code></td><td><code>expr % expr</code></td><td>Arithmetic remainder</td><td><code>Rem</code></td></tr>
|
||||
<tr><td><code>%=</code></td><td><code>var %= expr</code></td><td>Arithmetic remainder and assignment</td><td><code>RemAssign</code></td></tr>
|
||||
<tr><td><code>&</code></td><td><code>&expr</code>, <code>&mut expr</code></td><td>Borrow</td><td></td></tr>
|
||||
<tr><td><code>&</code></td><td><code>&type</code>, <code>&mut type</code>, <code>&'a type</code>, <code>&'a mut type</code></td><td>Borrowed pointer type</td><td></td></tr>
|
||||
<tr><td><code>&</code></td><td><code>expr & expr</code></td><td>Bitwise AND</td><td><code>BitAnd</code></td></tr>
|
||||
<tr><td><code>&=</code></td><td><code>var &= expr</code></td><td>Bitwise AND and assignment</td><td><code>BitAndAssign</code></td></tr>
|
||||
<tr><td><code>&&</code></td><td><code>expr && expr</code></td><td>Short-circuiting logical AND</td><td></td></tr>
|
||||
<tr><td><code>*</code></td><td><code>expr * expr</code></td><td>Arithmetic multiplication</td><td><code>Mul</code></td></tr>
|
||||
<tr><td><code>*=</code></td><td><code>var *= expr</code></td><td>Arithmetic multiplication and assignment</td><td><code>MulAssign</code></td></tr>
|
||||
<tr><td><code>*</code></td><td><code>*expr</code></td><td>Dereference</td><td><code>Deref</code></td></tr>
|
||||
<tr><td><code>*</code></td><td><code>*const type</code>, <code>*mut type</code></td><td>Raw pointer</td><td></td></tr>
|
||||
<tr><td><code>+</code></td><td><code>trait + trait</code>, <code>'a + trait</code></td><td>Compound type constraint</td><td></td></tr>
|
||||
<tr><td><code>+</code></td><td><code>expr + expr</code></td><td>Arithmetic addition</td><td><code>Add</code></td></tr>
|
||||
<tr><td><code>+=</code></td><td><code>var += expr</code></td><td>Arithmetic addition and assignment</td><td><code>AddAssign</code></td></tr>
|
||||
<tr><td><code>,</code></td><td><code>expr, expr</code></td><td>Argument and element separator</td><td></td></tr>
|
||||
<tr><td><code>-</code></td><td><code>- expr</code></td><td>Arithmetic negation</td><td><code>Neg</code></td></tr>
|
||||
<tr><td><code>-</code></td><td><code>expr - expr</code></td><td>Arithmetic subtraction</td><td><code>Sub</code></td></tr>
|
||||
<tr><td><code>-=</code></td><td><code>var -= expr</code></td><td>Arithmetic subtraction and assignment</td><td><code>SubAssign</code></td></tr>
|
||||
<tr><td><code>-></code></td><td><code>fn(...) -> type</code>, <code>|…| -> type</code></td><td>Function and closure return type</td><td></td></tr>
|
||||
<tr><td><code>.</code></td><td><code>expr.ident</code></td><td>Field access</td><td></td></tr>
|
||||
<tr><td><code>.</code></td><td><code>expr.ident(expr, ...)</code></td><td>Method call</td><td></td></tr>
|
||||
<tr><td><code>.</code></td><td><code>expr.0</code>, <code>expr.1</code>, and so on</td><td>Tuple indexing</td><td></td></tr>
|
||||
<tr><td><code>..</code></td><td><code>..</code>, <code>expr..</code>, <code>..expr</code>, <code>expr..expr</code></td><td>Right-exclusive range literal</td><td><code>PartialOrd</code></td></tr>
|
||||
<tr><td><code>..=</code></td><td><code>..=expr</code>, <code>expr..=expr</code></td><td>Right-inclusive range literal</td><td><code>PartialOrd</code></td></tr>
|
||||
<tr><td><code>..</code></td><td><code>..expr</code></td><td>Struct literal update syntax</td><td></td></tr>
|
||||
<tr><td><code>..</code></td><td><code>variant(x, ..)</code>, <code>struct_type { x, .. }</code></td><td>“And the rest” pattern binding</td><td></td></tr>
|
||||
<tr><td><code>...</code></td><td><code>expr...expr</code></td><td>(Deprecated, use <code>..=</code> instead) In a pattern: inclusive range pattern</td><td></td></tr>
|
||||
<tr><td><code>/</code></td><td><code>expr / expr</code></td><td>Arithmetic division</td><td><code>Div</code></td></tr>
|
||||
<tr><td><code>/=</code></td><td><code>var /= expr</code></td><td>Arithmetic division and assignment</td><td><code>DivAssign</code></td></tr>
|
||||
<tr><td><code>:</code></td><td><code>pat: type</code>, <code>ident: type</code></td><td>Constraints</td><td></td></tr>
|
||||
<tr><td><code>:</code></td><td><code>ident: expr</code></td><td>Struct field initializer</td><td></td></tr>
|
||||
<tr><td><code>:</code></td><td><code>'a: loop {...}</code></td><td>Loop label</td><td></td></tr>
|
||||
<tr><td><code>;</code></td><td><code>expr;</code></td><td>Statement and item terminator</td><td></td></tr>
|
||||
<tr><td><code>;</code></td><td><code>[...; len]</code></td><td>Part of fixed-size array syntax</td><td></td></tr>
|
||||
<tr><td><code><<</code></td><td><code>expr << expr</code></td><td>Left-shift</td><td><code>Shl</code></td></tr>
|
||||
<tr><td><code><<=</code></td><td><code>var <<= expr</code></td><td>Left-shift and assignment</td><td><code>ShlAssign</code></td></tr>
|
||||
<tr><td><code><</code></td><td><code>expr < expr</code></td><td>Less than comparison</td><td><code>PartialOrd</code></td></tr>
|
||||
<tr><td><code><=</code></td><td><code>expr <= expr</code></td><td>Less than or equal to comparison</td><td><code>PartialOrd</code></td></tr>
|
||||
<tr><td><code>=</code></td><td><code>var = expr</code>, <code>ident = type</code></td><td>Assignment/equivalence</td><td></td></tr>
|
||||
<tr><td><code>==</code></td><td><code>expr == expr</code></td><td>Equality comparison</td><td><code>PartialEq</code></td></tr>
|
||||
<tr><td><code>=></code></td><td><code>pat => expr</code></td><td>Part of match arm syntax</td><td></td></tr>
|
||||
<tr><td><code>></code></td><td><code>expr > expr</code></td><td>Greater than comparison</td><td><code>PartialOrd</code></td></tr>
|
||||
<tr><td><code>>=</code></td><td><code>expr >= expr</code></td><td>Greater than or equal to comparison</td><td><code>PartialOrd</code></td></tr>
|
||||
<tr><td><code>>></code></td><td><code>expr >> expr</code></td><td>Right-shift</td><td><code>Shr</code></td></tr>
|
||||
<tr><td><code>>>=</code></td><td><code>var >>= expr</code></td><td>Right-shift and assignment</td><td><code>ShrAssign</code></td></tr>
|
||||
<tr><td><code>@</code></td><td><code>ident @ pat</code></td><td>Pattern binding</td><td></td></tr>
|
||||
<tr><td><code>^</code></td><td><code>expr ^ expr</code></td><td>Bitwise exclusive OR</td><td><code>BitXor</code></td></tr>
|
||||
<tr><td><code>^=</code></td><td><code>var ^= expr</code></td><td>Bitwise exclusive OR and assignment</td><td><code>BitXorAssign</code></td></tr>
|
||||
<tr><td><code>|</code></td><td><code>pat | pat</code></td><td>Pattern alternatives</td><td></td></tr>
|
||||
<tr><td><code>|</code></td><td><code>expr | expr</code></td><td>Bitwise OR</td><td><code>BitOr</code></td></tr>
|
||||
<tr><td><code>|=</code></td><td><code>var |= expr</code></td><td>Bitwise OR and assignment</td><td><code>BitOrAssign</code></td></tr>
|
||||
<tr><td><code>||</code></td><td><code>expr || expr</code></td><td>Short-circuiting logical OR</td><td></td></tr>
|
||||
<tr><td><code>?</code></td><td><code>expr?</code></td><td>Error propagation</td><td></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<h3 id="non-operator-symbols"><a class="header" href="#non-operator-symbols">Non-operator Symbols</a></h3>
|
||||
<p>The following tables contain all symbols that don’t function as operators; that
|
||||
is, they don’t behave like a function or method call.</p>
|
||||
<p>Table B-2 shows symbols that appear on their own and are valid in a variety of
|
||||
locations.</p>
|
||||
<p><span class="caption">Table B-2: Stand-alone Syntax</span></p>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Symbol</th><th>Explanation</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><code>'ident</code></td><td>Named lifetime or loop label</td></tr>
|
||||
<tr><td>Digits immediately followed by <code>u8</code>, <code>i32</code>, <code>f64</code>, <code>usize</code>, and so on</td><td>Numeric literal of specific type</td></tr>
|
||||
<tr><td><code>"..."</code></td><td>String literal</td></tr>
|
||||
<tr><td><code>r"..."</code>, <code>r#"..."#</code>, <code>r##"..."##</code>, and so on</td><td>Raw string literal; escape characters not processed</td></tr>
|
||||
<tr><td><code>b"..."</code></td><td>Byte string literal; constructs an array of bytes instead of a string</td></tr>
|
||||
<tr><td><code>br"..."</code>, <code>br#"..."#</code>, <code>br##"..."##</code>, and so on</td><td>Raw byte string literal; combination of raw and byte string literal</td></tr>
|
||||
<tr><td><code>'...'</code></td><td>Character literal</td></tr>
|
||||
<tr><td><code>b'...'</code></td><td>ASCII byte literal</td></tr>
|
||||
<tr><td><code>|…| expr</code></td><td>Closure</td></tr>
|
||||
<tr><td><code>!</code></td><td>Always-empty bottom type for diverging functions</td></tr>
|
||||
<tr><td><code>_</code></td><td>“Ignored” pattern binding; also used to make integer literals readable</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p>Table B-3 shows symbols that appear in the context of a path through the module
|
||||
hierarchy to an item.</p>
|
||||
<p><span class="caption">Table B-3: Path-Related Syntax</span></p>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Symbol</th><th>Explanation</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><code>ident::ident</code></td><td>Namespace path</td></tr>
|
||||
<tr><td><code>::path</code></td><td>Path relative to the crate root (that is, an explicitly absolute path)</td></tr>
|
||||
<tr><td><code>self::path</code></td><td>Path relative to the current module (that is, an explicitly relative path)</td></tr>
|
||||
<tr><td><code>super::path</code></td><td>Path relative to the parent of the current module</td></tr>
|
||||
<tr><td><code>type::ident</code>, <code><type as trait>::ident</code></td><td>Associated constants, functions, and types</td></tr>
|
||||
<tr><td><code><type>::...</code></td><td>Associated item for a type that cannot be directly named (for example, <code><&T>::...</code>, <code><[T]>::...</code>, and so on)</td></tr>
|
||||
<tr><td><code>trait::method(...)</code></td><td>Disambiguating a method call by naming the trait that defines it</td></tr>
|
||||
<tr><td><code>type::method(...)</code></td><td>Disambiguating a method call by naming the type for which it’s defined</td></tr>
|
||||
<tr><td><code><type as trait>::method(...)</code></td><td>Disambiguating a method call by naming the trait and type</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p>Table B-4 shows symbols that appear in the context of using generic type
|
||||
parameters.</p>
|
||||
<p><span class="caption">Table B-4: Generics</span></p>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Symbol</th><th>Explanation</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><code>path<...></code></td><td>Specifies parameters to a generic type in a type (for example, <code>Vec<u8></code>)</td></tr>
|
||||
<tr><td><code>path::<...></code>, <code>method::<...></code></td><td>Specifies parameters to a generic type, function, or method in an expression; often referred to as <em>turbofish</em> (for example, <code>"42".parse::<i32>()</code>)</td></tr>
|
||||
<tr><td><code>fn ident<...> ...</code></td><td>Define generic function</td></tr>
|
||||
<tr><td><code>struct ident<...> ...</code></td><td>Define generic structure</td></tr>
|
||||
<tr><td><code>enum ident<...> ...</code></td><td>Define generic enumeration</td></tr>
|
||||
<tr><td><code>impl<...> ...</code></td><td>Define generic implementation</td></tr>
|
||||
<tr><td><code>for<...> type</code></td><td>Higher ranked lifetime bounds</td></tr>
|
||||
<tr><td><code>type<ident=type></code></td><td>A generic type where one or more associated types have specific assignments (for example, <code>Iterator<Item=T></code>)</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p>Table B-5 shows symbols that appear in the context of constraining generic type
|
||||
parameters with trait bounds.</p>
|
||||
<p><span class="caption">Table B-5: Trait Bound Constraints</span></p>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Symbol</th><th>Explanation</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><code>T: U</code></td><td>Generic parameter <code>T</code> constrained to types that implement <code>U</code></td></tr>
|
||||
<tr><td><code>T: 'a</code></td><td>Generic type <code>T</code> must outlive lifetime <code>'a</code> (meaning the type cannot transitively contain any references with lifetimes shorter than <code>'a</code>)</td></tr>
|
||||
<tr><td><code>T: 'static</code></td><td>Generic type <code>T</code> contains no borrowed references other than <code>'static</code> ones</td></tr>
|
||||
<tr><td><code>'b: 'a</code></td><td>Generic lifetime <code>'b</code> must outlive lifetime <code>'a</code></td></tr>
|
||||
<tr><td><code>T: ?Sized</code></td><td>Allow generic type parameter to be a dynamically sized type</td></tr>
|
||||
<tr><td><code>'a + trait</code>, <code>trait + trait</code></td><td>Compound type constraint</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p>Table B-6 shows symbols that appear in the context of calling or defining
|
||||
macros and specifying attributes on an item.</p>
|
||||
<p><span class="caption">Table B-6: Macros and Attributes</span></p>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Symbol</th><th>Explanation</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><code>#[meta]</code></td><td>Outer attribute</td></tr>
|
||||
<tr><td><code>#![meta]</code></td><td>Inner attribute</td></tr>
|
||||
<tr><td><code>$ident</code></td><td>Macro substitution</td></tr>
|
||||
<tr><td><code>$ident:kind</code></td><td>Macro metavariable</td></tr>
|
||||
<tr><td><code>$(...)...</code></td><td>Macro repetition</td></tr>
|
||||
<tr><td><code>ident!(...)</code>, <code>ident!{...}</code>, <code>ident![...]</code></td><td>Macro invocation</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p>Table B-7 shows symbols that create comments.</p>
|
||||
<p><span class="caption">Table B-7: Comments</span></p>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Symbol</th><th>Explanation</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><code>//</code></td><td>Line comment</td></tr>
|
||||
<tr><td><code>//!</code></td><td>Inner line doc comment</td></tr>
|
||||
<tr><td><code>///</code></td><td>Outer line doc comment</td></tr>
|
||||
<tr><td><code>/*...*/</code></td><td>Block comment</td></tr>
|
||||
<tr><td><code>/*!...*/</code></td><td>Inner block doc comment</td></tr>
|
||||
<tr><td><code>/**...*/</code></td><td>Outer block doc comment</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p>Table B-8 shows the contexts in which parentheses are used.</p>
|
||||
<p><span class="caption">Table B-8: Parentheses</span></p>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Symbol</th><th>Explanation</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><code>()</code></td><td>Empty tuple (aka unit), both literal and type</td></tr>
|
||||
<tr><td><code>(expr)</code></td><td>Parenthesized expression</td></tr>
|
||||
<tr><td><code>(expr,)</code></td><td>Single-element tuple expression</td></tr>
|
||||
<tr><td><code>(type,)</code></td><td>Single-element tuple type</td></tr>
|
||||
<tr><td><code>(expr, ...)</code></td><td>Tuple expression</td></tr>
|
||||
<tr><td><code>(type, ...)</code></td><td>Tuple type</td></tr>
|
||||
<tr><td><code>expr(expr, ...)</code></td><td>Function call expression; also used to initialize tuple <code>struct</code>s and tuple <code>enum</code> variants</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p>Table B-9 shows the contexts in which curly brackets are used.</p>
|
||||
<p><span class="caption">Table B-9: Curly Brackets</span></p>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Context</th><th>Explanation</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><code>{...}</code></td><td>Block expression</td></tr>
|
||||
<tr><td><code>Type {...}</code></td><td>Struct literal</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p>Table B-10 shows the contexts in which square brackets are used.</p>
|
||||
<p><span class="caption">Table B-10: Square Brackets</span></p>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Context</th><th>Explanation</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><code>[...]</code></td><td>Array literal</td></tr>
|
||||
<tr><td><code>[expr; len]</code></td><td>Array literal containing <code>len</code> copies of <code>expr</code></td></tr>
|
||||
<tr><td><code>[type; len]</code></td><td>Array type containing <code>len</code> instances of <code>type</code></td></tr>
|
||||
<tr><td><code>expr[expr]</code></td><td>Collection indexing; overloadable (<code>Index</code>, <code>IndexMut</code>)</td></tr>
|
||||
<tr><td><code>expr[..]</code>, <code>expr[a..]</code>, <code>expr[..b]</code>, <code>expr[a..b]</code></td><td>Collection indexing pretending to be collection slicing, using <code>Range</code>, <code>RangeFrom</code>, <code>RangeTo</code>, or <code>RangeFull</code> as the “index”</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
151
appendix/appendix-03-derivable-traits.html
Normal file
151
appendix/appendix-03-derivable-traits.html
Normal file
@@ -0,0 +1,151 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>C - Derivable Traits</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2 id="appendix-c-derivable-traits"><a class="header" href="#appendix-c-derivable-traits">Appendix C: Derivable Traits</a></h2>
|
||||
<p>In various places in the book, we’ve discussed the <code>derive</code> attribute, which
|
||||
you can apply to a struct or enum definition. The <code>derive</code> attribute generates
|
||||
code that will implement a trait with its own default implementation on the
|
||||
type you’ve annotated with the <code>derive</code> syntax.</p>
|
||||
<p>In this appendix, we provide a reference of all the traits in the standard
|
||||
library that you can use with <code>derive</code>. Each section covers:</p>
|
||||
<ul>
|
||||
<li>What operators and methods deriving this trait will enable</li>
|
||||
<li>What the implementation of the trait provided by <code>derive</code> does</li>
|
||||
<li>What implementing the trait signifies about the type</li>
|
||||
<li>The conditions in which you’re allowed or not allowed to implement the trait</li>
|
||||
<li>Examples of operations that require the trait</li>
|
||||
</ul>
|
||||
<p>If you want different behavior from that provided by the <code>derive</code> attribute,
|
||||
consult the <a href="../std/index.html">standard library documentation</a><!-- ignore -->
|
||||
for each trait for details on how to manually implement them.</p>
|
||||
<p>The traits listed here are the only ones defined by the standard library that
|
||||
can be implemented on your types using <code>derive</code>. Other traits defined in the
|
||||
standard library don’t have sensible default behavior, so it’s up to you to
|
||||
implement them in the way that makes sense for what you’re trying to accomplish.</p>
|
||||
<p>An example of a trait that can’t be derived is <code>Display</code>, which handles
|
||||
formatting for end users. You should always consider the appropriate way to
|
||||
display a type to an end user. What parts of the type should an end user be
|
||||
allowed to see? What parts would they find relevant? What format of the data
|
||||
would be most relevant to them? The Rust compiler doesn’t have this insight, so
|
||||
it can’t provide appropriate default behavior for you.</p>
|
||||
<p>The list of derivable traits provided in this appendix is not comprehensive:
|
||||
Libraries can implement <code>derive</code> for their own traits, making the list of
|
||||
traits you can use <code>derive</code> with truly open ended. Implementing <code>derive</code>
|
||||
involves using a procedural macro, which is covered in the <a href="../ch20/ch20-05-macros.html#custom-derive-macros">“Custom <code>derive</code>
|
||||
Macros”</a><!-- ignore --> section in Chapter 20.</p>
|
||||
<h3 id="debug-for-programmer-output"><a class="header" href="#debug-for-programmer-output"><code>Debug</code> for Programmer Output</a></h3>
|
||||
<p>The <code>Debug</code> trait enables debug formatting in format strings, which you
|
||||
indicate by adding <code>:?</code> within <code>{}</code> placeholders.</p>
|
||||
<p>The <code>Debug</code> trait allows you to print instances of a type for debugging
|
||||
purposes, so you and other programmers using your type can inspect an instance
|
||||
at a particular point in a program’s execution.</p>
|
||||
<p>The <code>Debug</code> trait is required, for example, in the use of the <code>assert_eq!</code>
|
||||
macro. This macro prints the values of instances given as arguments if the
|
||||
equality assertion fails so that programmers can see why the two instances
|
||||
weren’t equal.</p>
|
||||
<h3 id="partialeq-and-eq-for-equality-comparisons"><a class="header" href="#partialeq-and-eq-for-equality-comparisons"><code>PartialEq</code> and <code>Eq</code> for Equality Comparisons</a></h3>
|
||||
<p>The <code>PartialEq</code> trait allows you to compare instances of a type to check for
|
||||
equality and enables use of the <code>==</code> and <code>!=</code> operators.</p>
|
||||
<p>Deriving <code>PartialEq</code> implements the <code>eq</code> method. When <code>PartialEq</code> is derived on
|
||||
structs, two instances are equal only if <em>all</em> fields are equal, and the
|
||||
instances are not equal if <em>any</em> fields are not equal. When derived on enums,
|
||||
each variant is equal to itself and not equal to the other variants.</p>
|
||||
<p>The <code>PartialEq</code> trait is required, for example, with the use of the
|
||||
<code>assert_eq!</code> macro, which needs to be able to compare two instances of a type
|
||||
for equality.</p>
|
||||
<p>The <code>Eq</code> trait has no methods. Its purpose is to signal that for every value of
|
||||
the annotated type, the value is equal to itself. The <code>Eq</code> trait can only be
|
||||
applied to types that also implement <code>PartialEq</code>, although not all types that
|
||||
implement <code>PartialEq</code> can implement <code>Eq</code>. One example of this is floating-point
|
||||
number types: The implementation of floating-point numbers states that two
|
||||
instances of the not-a-number (<code>NaN</code>) value are not equal to each other.</p>
|
||||
<p>An example of when <code>Eq</code> is required is for keys in a <code>HashMap<K, V></code> so that
|
||||
the <code>HashMap<K, V></code> can tell whether two keys are the same.</p>
|
||||
<h3 id="partialord-and-ord-for-ordering-comparisons"><a class="header" href="#partialord-and-ord-for-ordering-comparisons"><code>PartialOrd</code> and <code>Ord</code> for Ordering Comparisons</a></h3>
|
||||
<p>The <code>PartialOrd</code> trait allows you to compare instances of a type for sorting
|
||||
purposes. A type that implements <code>PartialOrd</code> can be used with the <code><</code>, <code>></code>,
|
||||
<code><=</code>, and <code>>=</code> operators. You can only apply the <code>PartialOrd</code> trait to types
|
||||
that also implement <code>PartialEq</code>.</p>
|
||||
<p>Deriving <code>PartialOrd</code> implements the <code>partial_cmp</code> method, which returns an
|
||||
<code>Option<Ordering></code> that will be <code>None</code> when the values given don’t produce an
|
||||
ordering. An example of a value that doesn’t produce an ordering, even though
|
||||
most values of that type can be compared, is the <code>NaN</code> floating point value.
|
||||
Calling <code>partial_cmp</code> with any floating-point number and the <code>NaN</code>
|
||||
floating-point value will return <code>None</code>.</p>
|
||||
<p>When derived on structs, <code>PartialOrd</code> compares two instances by comparing the
|
||||
value in each field in the order in which the fields appear in the struct
|
||||
definition. When derived on enums, variants of the enum declared earlier in the
|
||||
enum definition are considered less than the variants listed later.</p>
|
||||
<p>The <code>PartialOrd</code> trait is required, for example, for the <code>gen_range</code> method
|
||||
from the <code>rand</code> crate that generates a random value in the range specified by a
|
||||
range expression.</p>
|
||||
<p>The <code>Ord</code> trait allows you to know that for any two values of the annotated
|
||||
type, a valid ordering will exist. The <code>Ord</code> trait implements the <code>cmp</code> method,
|
||||
which returns an <code>Ordering</code> rather than an <code>Option<Ordering></code> because a valid
|
||||
ordering will always be possible. You can only apply the <code>Ord</code> trait to types
|
||||
that also implement <code>PartialOrd</code> and <code>Eq</code> (and <code>Eq</code> requires <code>PartialEq</code>). When
|
||||
derived on structs and enums, <code>cmp</code> behaves the same way as the derived
|
||||
implementation for <code>partial_cmp</code> does with <code>PartialOrd</code>.</p>
|
||||
<p>An example of when <code>Ord</code> is required is when storing values in a <code>BTreeSet<T></code>,
|
||||
a data structure that stores data based on the sort order of the values.</p>
|
||||
<h3 id="clone-and-copy-for-duplicating-values"><a class="header" href="#clone-and-copy-for-duplicating-values"><code>Clone</code> and <code>Copy</code> for Duplicating Values</a></h3>
|
||||
<p>The <code>Clone</code> trait allows you to explicitly create a deep copy of a value, and
|
||||
the duplication process might involve running arbitrary code and copying heap
|
||||
data. See the <a href="../ch04/ch04-01-what-is-ownership.html#variables-and-data-interacting-with-clone">“Variables and Data Interacting with
|
||||
Clone”</a><!-- ignore --> section in
|
||||
Chapter 4 for more information on <code>Clone</code>.</p>
|
||||
<p>Deriving <code>Clone</code> implements the <code>clone</code> method, which when implemented for the
|
||||
whole type, calls <code>clone</code> on each of the parts of the type. This means all the
|
||||
fields or values in the type must also implement <code>Clone</code> to derive <code>Clone</code>.</p>
|
||||
<p>An example of when <code>Clone</code> is required is when calling the <code>to_vec</code> method on a
|
||||
slice. The slice doesn’t own the type instances it contains, but the vector
|
||||
returned from <code>to_vec</code> will need to own its instances, so <code>to_vec</code> calls
|
||||
<code>clone</code> on each item. Thus, the type stored in the slice must implement <code>Clone</code>.</p>
|
||||
<p>The <code>Copy</code> trait allows you to duplicate a value by only copying bits stored on
|
||||
the stack; no arbitrary code is necessary. See the <a href="../ch04/ch04-01-what-is-ownership.html#stack-only-data-copy">“Stack-Only Data:
|
||||
Copy”</a><!-- ignore --> section in Chapter 4 for more
|
||||
information on <code>Copy</code>.</p>
|
||||
<p>The <code>Copy</code> trait doesn’t define any methods to prevent programmers from
|
||||
overloading those methods and violating the assumption that no arbitrary code
|
||||
is being run. That way, all programmers can assume that copying a value will be
|
||||
very fast.</p>
|
||||
<p>You can derive <code>Copy</code> on any type whose parts all implement <code>Copy</code>. A type that
|
||||
implements <code>Copy</code> must also implement <code>Clone</code> because a type that implements
|
||||
<code>Copy</code> has a trivial implementation of <code>Clone</code> that performs the same task as
|
||||
<code>Copy</code>.</p>
|
||||
<p>The <code>Copy</code> trait is rarely required; types that implement <code>Copy</code> have
|
||||
optimizations available, meaning you don’t have to call <code>clone</code>, which makes
|
||||
the code more concise.</p>
|
||||
<p>Everything possible with <code>Copy</code> you can also accomplish with <code>Clone</code>, but the
|
||||
code might be slower or have to use <code>clone</code> in places.</p>
|
||||
<h3 id="hash-for-mapping-a-value-to-a-value-of-fixed-size"><a class="header" href="#hash-for-mapping-a-value-to-a-value-of-fixed-size"><code>Hash</code> for Mapping a Value to a Value of Fixed Size</a></h3>
|
||||
<p>The <code>Hash</code> trait allows you to take an instance of a type of arbitrary size and
|
||||
map that instance to a value of fixed size using a hash function. Deriving
|
||||
<code>Hash</code> implements the <code>hash</code> method. The derived implementation of the <code>hash</code>
|
||||
method combines the result of calling <code>hash</code> on each of the parts of the type,
|
||||
meaning all fields or values must also implement <code>Hash</code> to derive <code>Hash</code>.</p>
|
||||
<p>An example of when <code>Hash</code> is required is in storing keys in a <code>HashMap<K, V></code>
|
||||
to store data efficiently.</p>
|
||||
<h3 id="default-for-default-values"><a class="header" href="#default-for-default-values"><code>Default</code> for Default Values</a></h3>
|
||||
<p>The <code>Default</code> trait allows you to create a default value for a type. Deriving
|
||||
<code>Default</code> implements the <code>default</code> function. The derived implementation of the
|
||||
<code>default</code> function calls the <code>default</code> function on each part of the type,
|
||||
meaning all fields or values in the type must also implement <code>Default</code> to
|
||||
derive <code>Default</code>.</p>
|
||||
<p>The <code>Default::default</code> function is commonly used in combination with the struct
|
||||
update syntax discussed in the <a href="../ch05/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax">“Creating Instances from Other Instances with
|
||||
Struct Update
|
||||
Syntax”</a><!--
|
||||
ignore --> section in Chapter 5. You can customize a few fields of a struct and
|
||||
then set and use a default value for the rest of the fields by using
|
||||
<code>..Default::default()</code>.</p>
|
||||
<p>The <code>Default</code> trait is required when you use the method <code>unwrap_or_default</code> on
|
||||
<code>Option<T></code> instances, for example. If the <code>Option<T></code> is <code>None</code>, the method
|
||||
<code>unwrap_or_default</code> will return the result of <code>Default::default</code> for the type
|
||||
<code>T</code> stored in the <code>Option<T></code>.</p>
|
||||
</body>
|
||||
</html>
|
||||
121
appendix/appendix-04-useful-development-tools.html
Normal file
121
appendix/appendix-04-useful-development-tools.html
Normal file
@@ -0,0 +1,121 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>D - Useful Development Tools</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2 id="appendix-d-useful-development-tools"><a class="header" href="#appendix-d-useful-development-tools">Appendix D: Useful Development Tools</a></h2>
|
||||
<p>In this appendix, we talk about some useful development tools that the Rust
|
||||
project provides. We’ll look at automatic formatting, quick ways to apply
|
||||
warning fixes, a linter, and integrating with IDEs.</p>
|
||||
<h3 id="automatic-formatting-with-rustfmt"><a class="header" href="#automatic-formatting-with-rustfmt">Automatic Formatting with <code>rustfmt</code></a></h3>
|
||||
<p>The <code>rustfmt</code> tool reformats your code according to the community code style.
|
||||
Many collaborative projects use <code>rustfmt</code> to prevent arguments about which
|
||||
style to use when writing Rust: Everyone formats their code using the tool.</p>
|
||||
<p>Rust installations include <code>rustfmt</code> by default, so you should already have the
|
||||
programs <code>rustfmt</code> and <code>cargo-fmt</code> on your system. These two commands are
|
||||
analogous to <code>rustc</code> and <code>cargo</code> in that <code>rustfmt</code> allows finer grained control
|
||||
and <code>cargo-fmt</code> understands conventions of a project that uses Cargo. To format
|
||||
any Cargo project, enter the following:</p>
|
||||
<pre><code class="language-console">$ cargo fmt
|
||||
</code></pre>
|
||||
<p>Running this command reformats all the Rust code in the current crate. This
|
||||
should only change the code style, not the code semantics. For more information
|
||||
on <code>rustfmt</code>, see <a href="https://github.com/rust-lang/rustfmt">its documentation</a>.</p>
|
||||
<h3 id="fix-your-code-with-rustfix"><a class="header" href="#fix-your-code-with-rustfix">Fix Your Code with <code>rustfix</code></a></h3>
|
||||
<p>The <code>rustfix</code> tool is included with Rust installations and can automatically
|
||||
fix compiler warnings that have a clear way to correct the problem that’s
|
||||
likely what you want. You’ve probably seen compiler warnings before. For
|
||||
example, consider this code:</p>
|
||||
<p><span class="filename">Filename: src/main.rs</span></p>
|
||||
<pre class="playground"><code class="language-rust edition2024">fn main() {
|
||||
let mut x = 42;
|
||||
println!("{x}");
|
||||
}</code></pre>
|
||||
<p>Here, we’re defining the variable <code>x</code> as mutable, but we never actually mutate
|
||||
it. Rust warns us about that:</p>
|
||||
<pre><code class="language-console">$ cargo build
|
||||
Compiling myprogram v0.1.0 (file:///projects/myprogram)
|
||||
warning: variable does not need to be mutable
|
||||
--> src/main.rs:2:9
|
||||
|
|
||||
2 | let mut x = 0;
|
||||
| ----^
|
||||
| |
|
||||
| help: remove this `mut`
|
||||
|
|
||||
= note: `#[warn(unused_mut)]` on by default
|
||||
</code></pre>
|
||||
<p>The warning suggests that we remove the <code>mut</code> keyword. We can automatically
|
||||
apply that suggestion using the <code>rustfix</code> tool by running the command <code>cargo fix</code>:</p>
|
||||
<pre><code class="language-console">$ cargo fix
|
||||
Checking myprogram v0.1.0 (file:///projects/myprogram)
|
||||
Fixing src/main.rs (1 fix)
|
||||
Finished dev [unoptimized + debuginfo] target(s) in 0.59s
|
||||
</code></pre>
|
||||
<p>When we look at <em>src/main.rs</em> again, we’ll see that <code>cargo fix</code> has changed the
|
||||
code:</p>
|
||||
<p><span class="filename">Filename: src/main.rs</span></p>
|
||||
<pre class="playground"><code class="language-rust edition2024">fn main() {
|
||||
let x = 42;
|
||||
println!("{x}");
|
||||
}</code></pre>
|
||||
<p>The variable <code>x</code> is now immutable, and the warning no longer appears.</p>
|
||||
<p>You can also use the <code>cargo fix</code> command to transition your code between
|
||||
different Rust editions. Editions are covered in <a href="appendix-05-editions.html">Appendix E</a><!--
|
||||
ignore -->.</p>
|
||||
<h3 id="more-lints-with-clippy"><a class="header" href="#more-lints-with-clippy">More Lints with Clippy</a></h3>
|
||||
<p>The Clippy tool is a collection of lints to analyze your code so that you can
|
||||
catch common mistakes and improve your Rust code. Clippy is included with
|
||||
standard Rust installations.</p>
|
||||
<p>To run Clippy’s lints on any Cargo project, enter the following:</p>
|
||||
<pre><code class="language-console">$ cargo clippy
|
||||
</code></pre>
|
||||
<p>For example, say you write a program that uses an approximation of a
|
||||
mathematical constant, such as pi, as this program does:</p>
|
||||
<figure class="listing">
|
||||
<span class="file-name">Filename: src/main.rs</span>
|
||||
<pre class="playground"><code class="language-rust edition2024">fn main() {
|
||||
let x = 3.1415;
|
||||
let r = 8.0;
|
||||
println!("the area of the circle is {}", x * r * r);
|
||||
}</code></pre>
|
||||
</figure>
|
||||
<p>Running <code>cargo clippy</code> on this project results in this error:</p>
|
||||
<pre><code class="language-text">error: approximate value of `f{32, 64}::consts::PI` found
|
||||
--> src/main.rs:2:13
|
||||
|
|
||||
2 | let x = 3.1415;
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: `#[deny(clippy::approx_constant)]` on by default
|
||||
= help: consider using the constant directly
|
||||
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant
|
||||
</code></pre>
|
||||
<p>This error lets you know that Rust already has a more precise <code>PI</code> constant
|
||||
defined, and that your program would be more correct if you used the constant
|
||||
instead. You would then change your code to use the <code>PI</code> constant.</p>
|
||||
<p>The following code doesn’t result in any errors or warnings from Clippy:</p>
|
||||
<figure class="listing">
|
||||
<span class="file-name">Filename: src/main.rs</span>
|
||||
<pre class="playground"><code class="language-rust edition2024">fn main() {
|
||||
let x = std::f64::consts::PI;
|
||||
let r = 8.0;
|
||||
println!("the area of the circle is {}", x * r * r);
|
||||
}</code></pre>
|
||||
</figure>
|
||||
<p>For more information on Clippy, see <a href="https://github.com/rust-lang/rust-clippy">its documentation</a>.</p>
|
||||
<h3 id="ide-integration-using-rust-analyzer"><a class="header" href="#ide-integration-using-rust-analyzer">IDE Integration Using <code>rust-analyzer</code></a></h3>
|
||||
<p>To help with IDE integration, the Rust community recommends using
|
||||
<a href="https://rust-analyzer.github.io"><code>rust-analyzer</code></a><!-- ignore -->. This tool is a set of
|
||||
compiler-centric utilities that speak <a href="http://langserver.org/">Language Server Protocol</a><!--
|
||||
ignore -->, which is a specification for IDEs and programming languages to
|
||||
communicate with each other. Different clients can use <code>rust-analyzer</code>, such as
|
||||
<a href="https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer">the Rust analyzer plug-in for Visual Studio Code</a>.</p>
|
||||
<p>Visit the <code>rust-analyzer</code> project’s <a href="https://rust-analyzer.github.io">home page</a><!-- ignore -->
|
||||
for installation instructions, then install the language server support in your
|
||||
particular IDE. Your IDE will gain capabilities such as autocompletion, jump to
|
||||
definition, and inline errors.</p>
|
||||
</body>
|
||||
</html>
|
||||
57
appendix/appendix-05-editions.html
Normal file
57
appendix/appendix-05-editions.html
Normal file
@@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>E - Editions</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2 id="appendix-e-editions"><a class="header" href="#appendix-e-editions">Appendix E: Editions</a></h2>
|
||||
<p>In Chapter 1, you saw that <code>cargo new</code> adds a bit of metadata to your
|
||||
<em>Cargo.toml</em> file about an edition. This appendix talks about what that means!</p>
|
||||
<p>The Rust language and compiler have a six-week release cycle, meaning users get
|
||||
a constant stream of new features. Other programming languages release larger
|
||||
changes less often; Rust releases smaller updates more frequently. After a
|
||||
while, all of these tiny changes add up. But from release to release, it can be
|
||||
difficult to look back and say, “Wow, between Rust 1.10 and Rust 1.31, Rust has
|
||||
changed a lot!”</p>
|
||||
<p>Every three years or so, the Rust team produces a new Rust <em>edition</em>. Each
|
||||
edition brings together the features that have landed into a clear package with
|
||||
fully updated documentation and tooling. New editions ship as part of the usual
|
||||
six-week release process.</p>
|
||||
<p>Editions serve different purposes for different people:</p>
|
||||
<ul>
|
||||
<li>For active Rust users, a new edition brings together incremental changes into
|
||||
an easy-to-understand package.</li>
|
||||
<li>For non-users, a new edition signals that some major advancements have
|
||||
landed, which might make Rust worth another look.</li>
|
||||
<li>For those developing Rust, a new edition provides a rallying point for the
|
||||
project as a whole.</li>
|
||||
</ul>
|
||||
<p>At the time of this writing, four Rust editions are available: Rust 2015, Rust
|
||||
2018, Rust 2021, and Rust 2024. This book is written using Rust 2024 edition
|
||||
idioms.</p>
|
||||
<p>The <code>edition</code> key in <em>Cargo.toml</em> indicates which edition the compiler should
|
||||
use for your code. If the key doesn’t exist, Rust uses <code>2015</code> as the edition
|
||||
value for backward compatibility reasons.</p>
|
||||
<p>Each project can opt in to an edition other than the default 2015 edition.
|
||||
Editions can contain incompatible changes, such as including a new keyword that
|
||||
conflicts with identifiers in code. However, unless you opt in to those
|
||||
changes, your code will continue to compile even as you upgrade the Rust
|
||||
compiler version you use.</p>
|
||||
<p>All Rust compiler versions support any edition that existed prior to that
|
||||
compiler’s release, and they can link crates of any supported editions
|
||||
together. Edition changes only affect the way the compiler initially parses
|
||||
code. Therefore, if you’re using Rust 2015 and one of your dependencies uses
|
||||
Rust 2018, your project will compile and be able to use that dependency. The
|
||||
opposite situation, where your project uses Rust 2018 and a dependency uses
|
||||
Rust 2015, works as well.</p>
|
||||
<p>To be clear: Most features will be available on all editions. Developers using
|
||||
any Rust edition will continue to see improvements as new stable releases are
|
||||
made. However, in some cases, mainly when new keywords are added, some new
|
||||
features might only be available in later editions. You will need to switch
|
||||
editions if you want to take advantage of such features.</p>
|
||||
<p>For more details, see <a href="https://doc.rust-lang.org/stable/edition-guide"><em>The Rust Edition Guide</em></a>. This is a
|
||||
complete book that enumerates the differences between editions and explains how
|
||||
to automatically upgrade your code to a new edition via <code>cargo fix</code>.</p>
|
||||
</body>
|
||||
</html>
|
||||
39
appendix/appendix-06-translation.html
Normal file
39
appendix/appendix-06-translation.html
Normal file
@@ -0,0 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>F - Translations of the Book</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2 id="appendix-f-translations-of-the-book"><a class="header" href="#appendix-f-translations-of-the-book">Appendix F: Translations of the Book</a></h2>
|
||||
<p>For resources in languages other than English. Most are still in progress; see
|
||||
<a href="https://github.com/rust-lang/book/issues?q=is%3Aopen+is%3Aissue+label%3ATranslations">the Translations label</a> to help or let us know about a new translation!</p>
|
||||
<ul>
|
||||
<li><a href="https://github.com/rust-br/rust-book-pt-br">Português</a> (BR)</li>
|
||||
<li><a href="https://github.com/nunojesus/rust-book-pt-pt">Português</a> (PT)</li>
|
||||
<li>简体中文: <a href="https://github.com/KaiserY/trpl-zh-cn">KaiserY/trpl-zh-cn</a>, <a href="https://github.com/gnu4cn/rust-lang-Zh_CN">gnu4cn/rust-lang-Zh_CN</a></li>
|
||||
<li><a href="https://github.com/rust-tw/book-tw">正體中文</a></li>
|
||||
<li><a href="https://rust-lang-ua.github.io/rustbook_ukrainian">Українська</a></li>
|
||||
<li><a href="https://github.com/thecodix/book">Español</a>, <a href="https://github.com/ManRR/rust-book-es">alternate</a>, <a href="https://github.com/RustLangES/rust-book-es">Español por RustLangES</a></li>
|
||||
<li><a href="https://github.com/rust-lang-ru/book">Русский</a></li>
|
||||
<li><a href="https://github.com/rust-kr/doc.rust-kr.org">한국어</a></li>
|
||||
<li><a href="https://github.com/rust-lang-ja/book-ja">日本語</a></li>
|
||||
<li><a href="https://github.com/Jimskapt/rust-book-fr">Français</a></li>
|
||||
<li><a href="https://github.com/paytchoo/book-pl">Polski</a></li>
|
||||
<li><a href="https://github.com/agentzero1/book">Cebuano</a></li>
|
||||
<li><a href="https://github.com/josephace135/book">Tagalog</a></li>
|
||||
<li><a href="https://github.com/psychoslave/Rust-libro">Esperanto</a></li>
|
||||
<li><a href="https://github.com/TChatzigiannakis/rust-book-greek">ελληνική</a></li>
|
||||
<li><a href="https://github.com/sebras/book">Svenska</a></li>
|
||||
<li><a href="https://github.com/RustFarsi/book">Farsi</a>, <a href="https://github.com/persian-rust/book">Persian (FA)</a></li>
|
||||
<li><a href="https://github.com/rust-lang-de/rustbook-de">Deutsch</a></li>
|
||||
<li><a href="https://github.com/venkatarun95/rust-book-hindi">हिंदी</a></li>
|
||||
<li><a href="https://github.com/rust-lang-th/book-th">ไทย</a></li>
|
||||
<li><a href="https://github.com/DanKHansen/book-dk">Danske</a></li>
|
||||
<li><a href="https://github.com/rust-lang-uz/book">O’zbek</a></li>
|
||||
<li><a href="https://github.com/tuanemdev/rust-book-vn">Tiếng Việt</a></li>
|
||||
<li><a href="https://nixxo.github.io/rust-lang-book-it/">Italiano</a></li>
|
||||
<li><a href="https://github.com/IsmailHosenIsmailJames/rust-book-bn">বাংলা</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
166
appendix/appendix-07-nightly-rust.html
Normal file
166
appendix/appendix-07-nightly-rust.html
Normal file
@@ -0,0 +1,166 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>G - How Rust is Made and “Nightly Rust”</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2 id="appendix-g---how-rust-is-made-and-nightly-rust"><a class="header" href="#appendix-g---how-rust-is-made-and-nightly-rust">Appendix G - How Rust is Made and “Nightly Rust”</a></h2>
|
||||
<p>This appendix is about how Rust is made and how that affects you as a Rust
|
||||
developer.</p>
|
||||
<h3 id="stability-without-stagnation"><a class="header" href="#stability-without-stagnation">Stability Without Stagnation</a></h3>
|
||||
<p>As a language, Rust cares a <em>lot</em> about the stability of your code. We want
|
||||
Rust to be a rock-solid foundation you can build on, and if things were
|
||||
constantly changing, that would be impossible. At the same time, if we can’t
|
||||
experiment with new features, we may not find out important flaws until after
|
||||
their release, when we can no longer change things.</p>
|
||||
<p>Our solution to this problem is what we call “stability without stagnation”,
|
||||
and our guiding principle is this: you should never have to fear upgrading to a
|
||||
new version of stable Rust. Each upgrade should be painless, but should also
|
||||
bring you new features, fewer bugs, and faster compile times.</p>
|
||||
<h3 id="choo-choo-release-channels-and-riding-the-trains"><a class="header" href="#choo-choo-release-channels-and-riding-the-trains">Choo, Choo! Release Channels and Riding the Trains</a></h3>
|
||||
<p>Rust development operates on a <em>train schedule</em>. That is, all development is
|
||||
done in the main branch of the Rust repository. Releases follow a software
|
||||
release train model, which has been used by Cisco IOS and other software
|
||||
projects. There are three <em>release channels</em> for Rust:</p>
|
||||
<ul>
|
||||
<li>Nightly</li>
|
||||
<li>Beta</li>
|
||||
<li>Stable</li>
|
||||
</ul>
|
||||
<p>Most Rust developers primarily use the stable channel, but those who want to
|
||||
try out experimental new features may use nightly or beta.</p>
|
||||
<p>Here’s an example of how the development and release process works: let’s
|
||||
assume that the Rust team is working on the release of Rust 1.5. That release
|
||||
happened in December of 2015, but it will provide us with realistic version
|
||||
numbers. A new feature is added to Rust: a new commit lands on the main
|
||||
branch. Each night, a new nightly version of Rust is produced. Every day is a
|
||||
release day, and these releases are created by our release infrastructure
|
||||
automatically. So as time passes, our releases look like this, once a night:</p>
|
||||
<pre><code class="language-text">nightly: * - - * - - *
|
||||
</code></pre>
|
||||
<p>Every six weeks, it’s time to prepare a new release! The <code>beta</code> branch of the
|
||||
Rust repository branches off from the main branch used by nightly. Now,
|
||||
there are two releases:</p>
|
||||
<pre><code class="language-text">nightly: * - - * - - *
|
||||
|
|
||||
beta: *
|
||||
</code></pre>
|
||||
<p>Most Rust users do not use beta releases actively, but test against beta in
|
||||
their CI system to help Rust discover possible regressions. In the meantime,
|
||||
there’s still a nightly release every night:</p>
|
||||
<pre><code class="language-text">nightly: * - - * - - * - - * - - *
|
||||
|
|
||||
beta: *
|
||||
</code></pre>
|
||||
<p>Let’s say a regression is found. Good thing we had some time to test the beta
|
||||
release before the regression snuck into a stable release! The fix is applied
|
||||
to the main branch, so that nightly is fixed, and then the fix is backported to
|
||||
the <code>beta</code> branch, and a new release of beta is produced:</p>
|
||||
<pre><code class="language-text">nightly: * - - * - - * - - * - - * - - *
|
||||
|
|
||||
beta: * - - - - - - - - *
|
||||
</code></pre>
|
||||
<p>Six weeks after the first beta was created, it’s time for a stable release! The
|
||||
<code>stable</code> branch is produced from the <code>beta</code> branch:</p>
|
||||
<pre><code class="language-text">nightly: * - - * - - * - - * - - * - - * - * - *
|
||||
|
|
||||
beta: * - - - - - - - - *
|
||||
|
|
||||
stable: *
|
||||
</code></pre>
|
||||
<p>Hooray! Rust 1.5 is done! However, we’ve forgotten one thing: because the six
|
||||
weeks have gone by, we also need a new beta of the <em>next</em> version of Rust, 1.6.
|
||||
So after <code>stable</code> branches off of <code>beta</code>, the next version of <code>beta</code> branches
|
||||
off of <code>nightly</code> again:</p>
|
||||
<pre><code class="language-text">nightly: * - - * - - * - - * - - * - - * - * - *
|
||||
| |
|
||||
beta: * - - - - - - - - * *
|
||||
|
|
||||
stable: *
|
||||
</code></pre>
|
||||
<p>This is called the “train model” because every six weeks, a release “leaves the
|
||||
station”, but still has to take a journey through the beta channel before it
|
||||
arrives as a stable release.</p>
|
||||
<p>Rust releases every six weeks, like clockwork. If you know the date of one Rust
|
||||
release, you can know the date of the next one: it’s six weeks later. A nice
|
||||
aspect of having releases scheduled every six weeks is that the next train is
|
||||
coming soon. If a feature happens to miss a particular release, there’s no need
|
||||
to worry: another one is happening in a short time! This helps reduce pressure
|
||||
to sneak possibly unpolished features in close to the release deadline.</p>
|
||||
<p>Thanks to this process, you can always check out the next build of Rust and
|
||||
verify for yourself that it’s easy to upgrade to: if a beta release doesn’t
|
||||
work as expected, you can report it to the team and get it fixed before the
|
||||
next stable release happens! Breakage in a beta release is relatively rare, but
|
||||
<code>rustc</code> is still a piece of software, and bugs do exist.</p>
|
||||
<h3 id="maintenance-time"><a class="header" href="#maintenance-time">Maintenance time</a></h3>
|
||||
<p>The Rust project supports the most recent stable version. When a new stable
|
||||
version is released, the old version reaches its end of life (EOL). This means
|
||||
each version is supported for six weeks.</p>
|
||||
<h3 id="unstable-features"><a class="header" href="#unstable-features">Unstable Features</a></h3>
|
||||
<p>There’s one more catch with this release model: unstable features. Rust uses a
|
||||
technique called “feature flags” to determine what features are enabled in a
|
||||
given release. If a new feature is under active development, it lands on the
|
||||
main branch, and therefore, in nightly, but behind a <em>feature flag</em>. If you, as
|
||||
a user, wish to try out the work-in-progress feature, you can, but you must be
|
||||
using a nightly release of Rust and annotate your source code with the
|
||||
appropriate flag to opt in.</p>
|
||||
<p>If you’re using a beta or stable release of Rust, you can’t use any feature
|
||||
flags. This is the key that allows us to get practical use with new features
|
||||
before we declare them stable forever. Those who wish to opt into the bleeding
|
||||
edge can do so, and those who want a rock-solid experience can stick with
|
||||
stable and know that their code won’t break. Stability without stagnation.</p>
|
||||
<p>This book only contains information about stable features, as in-progress
|
||||
features are still changing, and surely they’ll be different between when this
|
||||
book was written and when they get enabled in stable builds. You can find
|
||||
documentation for nightly-only features online.</p>
|
||||
<h3 id="rustup-and-the-role-of-rust-nightly"><a class="header" href="#rustup-and-the-role-of-rust-nightly">Rustup and the Role of Rust Nightly</a></h3>
|
||||
<p>Rustup makes it easy to change between different release channels of Rust, on a
|
||||
global or per-project basis. By default, you’ll have stable Rust installed. To
|
||||
install nightly, for example:</p>
|
||||
<pre><code class="language-console">$ rustup toolchain install nightly
|
||||
</code></pre>
|
||||
<p>You can see all of the <em>toolchains</em> (releases of Rust and associated
|
||||
components) you have installed with <code>rustup</code> as well. Here’s an example on one
|
||||
of your authors’ Windows computer:</p>
|
||||
<pre><code class="language-powershell">> rustup toolchain list
|
||||
stable-x86_64-pc-windows-msvc (default)
|
||||
beta-x86_64-pc-windows-msvc
|
||||
nightly-x86_64-pc-windows-msvc
|
||||
</code></pre>
|
||||
<p>As you can see, the stable toolchain is the default. Most Rust users use stable
|
||||
most of the time. You might want to use stable most of the time, but use
|
||||
nightly on a specific project, because you care about a cutting-edge feature.
|
||||
To do so, you can use <code>rustup override</code> in that project’s directory to set the
|
||||
nightly toolchain as the one <code>rustup</code> should use when you’re in that directory:</p>
|
||||
<pre><code class="language-console">$ cd ~/projects/needs-nightly
|
||||
$ rustup override set nightly
|
||||
</code></pre>
|
||||
<p>Now, every time you call <code>rustc</code> or <code>cargo</code> inside of
|
||||
<em>~/projects/needs-nightly</em>, <code>rustup</code> will make sure that you are using nightly
|
||||
Rust, rather than your default of stable Rust. This comes in handy when you
|
||||
have a lot of Rust projects!</p>
|
||||
<h3 id="the-rfc-process-and-teams"><a class="header" href="#the-rfc-process-and-teams">The RFC Process and Teams</a></h3>
|
||||
<p>So how do you learn about these new features? Rust’s development model follows
|
||||
a <em>Request For Comments (RFC) process</em>. If you’d like an improvement in Rust,
|
||||
you can write up a proposal, called an RFC.</p>
|
||||
<p>Anyone can write RFCs to improve Rust, and the proposals are reviewed and
|
||||
discussed by the Rust team, which is comprised of many topic subteams. There’s
|
||||
a full list of the teams <a href="https://www.rust-lang.org/governance">on Rust’s website</a>, which includes teams for
|
||||
each area of the project: language design, compiler implementation,
|
||||
infrastructure, documentation, and more. The appropriate team reads the
|
||||
proposal and the comments, writes some comments of their own, and eventually,
|
||||
there’s consensus to accept or reject the feature.</p>
|
||||
<p>If the feature is accepted, an issue is opened on the Rust repository, and
|
||||
someone can implement it. The person who implements it very well may not be the
|
||||
person who proposed the feature in the first place! When the implementation is
|
||||
ready, it lands on the main branch behind a feature gate, as we discussed in
|
||||
the <a href="#unstable-features">“Unstable Features”</a><!-- ignore --> section.</p>
|
||||
<p>After some time, once Rust developers who use nightly releases have been able
|
||||
to try out the new feature, team members will discuss the feature, how it’s
|
||||
worked out on nightly, and decide if it should make it into stable Rust or not.
|
||||
If the decision is to move forward, the feature gate is removed, and the
|
||||
feature is now considered stable! It rides the trains into a new stable release
|
||||
of Rust.</p>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user