diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fcdcb905d1..3b17fba9aa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,7 +17,7 @@ jobs: - name: Install mdbook run: | mkdir bin - curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.3.5/mdbook-v0.3.5-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin + curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.3.7/mdbook-v0.3.7-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin echo "##[add-path]$(pwd)/bin" - name: Report versions run: | @@ -41,7 +41,7 @@ jobs: - name: Install mdbook run: | mkdir bin - curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.3.5/mdbook-v0.3.5-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin + curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.3.7/mdbook-v0.3.7-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin echo "##[add-path]$(pwd)/bin" - name: Report versions run: | @@ -51,7 +51,7 @@ jobs: - name: Spellcheck run: bash ci/spellcheck.sh list - name: Lint for local file paths - run: | + run: | mdbook build cargo run --bin lfp src - name: Validate references @@ -61,4 +61,4 @@ jobs: curl -sSLo linkcheck.sh \ https://raw.githubusercontent.com/rust-lang/rust/master/src/tools/linkchecker/linkcheck.sh # Cannot use --all here because of the generated redirect pages aren't available. - sh linkcheck.sh book \ No newline at end of file + sh linkcheck.sh book diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 95151cbee9..8710bd2b2f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,7 +25,7 @@ comments for any suggestions or corrections! If you're looking for ways to help that don't involve large amounts of reading or writing, check out the [open issues with the E-help-wanted -label][help-wanted]. These might be small fixes to the text Rust code, +label][help-wanted]. These might be small fixes to the text, Rust code, frontend code, or shell scripts that would help us be more efficient or enhance the book in some way! diff --git a/ci/dictionary.txt b/ci/dictionary.txt index fa7d0a0f0b..d1ba6379d5 100644 --- a/ci/dictionary.txt +++ b/ci/dictionary.txt @@ -69,6 +69,7 @@ chXX chYY clippy clippy's +cmdlet coercions combinator ConcreteType diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/src/main.rs index 7704ff3382..9d8d9bfb5b 100644 --- a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/src/main.rs +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/src/main.rs @@ -1,8 +1,8 @@ // ANCHOR: here -fn largest(list: &[i32]) -> i32 { - let mut largest = list[0]; +fn largest(list: &[i32]) -> &i32 { + let mut largest = &list[0]; - for &item in list { + for item in list { if item > largest { largest = item; } @@ -17,7 +17,7 @@ fn main() { let result = largest(&number_list); println!("The largest number is {}", result); // ANCHOR_END: here - assert_eq!(result, 100); + assert_eq!(result, &100); // ANCHOR: here let number_list = vec![102, 34, 6000, 89, 54, 2, 43, 8]; @@ -25,7 +25,7 @@ fn main() { let result = largest(&number_list); println!("The largest number is {}", result); // ANCHOR_END: here - assert_eq!(result, 6000); + assert_eq!(result, &6000); // ANCHOR: here } // ANCHOR_END: here diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/src/main.rs index 6b483ec976..3e2f98aab0 100644 --- a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/src/main.rs +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/src/main.rs @@ -1,8 +1,8 @@ // ANCHOR: here -fn largest_i32(list: &[i32]) -> i32 { - let mut largest = list[0]; +fn largest_i32(list: &[i32]) -> &i32 { + let mut largest = &list[0]; - for &item in list { + for item in list { if item > largest { largest = item; } @@ -11,10 +11,10 @@ fn largest_i32(list: &[i32]) -> i32 { largest } -fn largest_char(list: &[char]) -> char { - let mut largest = list[0]; +fn largest_char(list: &[char]) -> &char { + let mut largest = &list[0]; - for &item in list { + for item in list { if item > largest { largest = item; } @@ -29,7 +29,7 @@ fn main() { let result = largest_i32(&number_list); println!("The largest number is {}", result); // ANCHOR_END: here - assert_eq!(result, 100); + assert_eq!(result, &100); // ANCHOR: here let char_list = vec!['y', 'm', 'a', 'q']; @@ -37,7 +37,7 @@ fn main() { let result = largest_char(&char_list); println!("The largest char is {}", result); // ANCHOR_END: here - assert_eq!(result, 'y'); + assert_eq!(result, &'y'); // ANCHOR: here } // ANCHOR_END: here diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/src/main.rs index e731157060..814fddc509 100644 --- a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/src/main.rs +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/src/main.rs @@ -1,7 +1,7 @@ -fn largest(list: &[T]) -> T { +fn largest(list: &[T]) -> &T { let mut largest = list[0]; - for &item in list { + for item in list { if item > largest { largest = item; } diff --git a/listings/ch13-functional-features/listing-13-26/src/lib.rs b/listings/ch13-functional-features/listing-13-26/src/lib.rs index 44f0c7ee21..2cb0bea7dd 100644 --- a/listings/ch13-functional-features/listing-13-26/src/lib.rs +++ b/listings/ch13-functional-features/listing-13-26/src/lib.rs @@ -10,7 +10,7 @@ pub struct Config { // ANCHOR: here impl Config { - pub fn new(mut args: std::env::Args) -> Result { + pub fn new(mut args: env::Args) -> Result { // --snip-- // ANCHOR_END: here if args.len() < 3 { diff --git a/listings/ch13-functional-features/listing-13-27/src/lib.rs b/listings/ch13-functional-features/listing-13-27/src/lib.rs index a4c58d9bdd..61d828aab4 100644 --- a/listings/ch13-functional-features/listing-13-27/src/lib.rs +++ b/listings/ch13-functional-features/listing-13-27/src/lib.rs @@ -10,7 +10,7 @@ pub struct Config { // ANCHOR: here impl Config { - pub fn new(mut args: std::env::Args) -> Result { + pub fn new(mut args: env::Args) -> Result { args.next(); let query = match args.next() { diff --git a/listings/ch15-smart-pointers/listing-15-24/output.txt b/listings/ch15-smart-pointers/listing-15-24/output.txt index bfe217bf41..21b3530d95 100644 --- a/listings/ch15-smart-pointers/listing-15-24/output.txt +++ b/listings/ch15-smart-pointers/listing-15-24/output.txt @@ -3,5 +3,5 @@ $ cargo run Finished dev [unoptimized + debuginfo] target(s) in 0.63s Running `target/debug/cons-list` a after = Cons(RefCell { value: 15 }, Nil) -b after = Cons(RefCell { value: 6 }, Cons(RefCell { value: 15 }, Nil)) -c after = Cons(RefCell { value: 10 }, Cons(RefCell { value: 15 }, Nil)) +b after = Cons(RefCell { value: 3 }, Cons(RefCell { value: 15 }, Nil)) +c after = Cons(RefCell { value: 4 }, Cons(RefCell { value: 15 }, Nil)) diff --git a/listings/ch15-smart-pointers/listing-15-24/src/main.rs b/listings/ch15-smart-pointers/listing-15-24/src/main.rs index ac271fa21f..e225bd8620 100644 --- a/listings/ch15-smart-pointers/listing-15-24/src/main.rs +++ b/listings/ch15-smart-pointers/listing-15-24/src/main.rs @@ -13,8 +13,8 @@ fn main() { let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil))); - let b = Cons(Rc::new(RefCell::new(6)), Rc::clone(&a)); - let c = Cons(Rc::new(RefCell::new(10)), Rc::clone(&a)); + let b = Cons(Rc::new(RefCell::new(3)), Rc::clone(&a)); + let c = Cons(Rc::new(RefCell::new(4)), Rc::clone(&a)); *value.borrow_mut() += 10; diff --git a/src/appendix-06-translation.md b/src/appendix-06-translation.md index 553ac8cd3c..1b6388157d 100644 --- a/src/appendix-06-translation.md +++ b/src/appendix-06-translation.md @@ -23,3 +23,4 @@ For resources in languages other than English. Most are still in progress; see - [ελληνική](https://github.com/TChatzigiannakis/rust-book-greek) - [Svenska](https://github.com/sebras/book) - [Farsi](https://github.com/pomokhtari/rust-book-fa) +- [Deutsch](https://github.com/rust-lang-de/rustbook-de) diff --git a/src/ch01-03-hello-cargo.md b/src/ch01-03-hello-cargo.md index 61b2927ba0..e81f5b6d87 100644 --- a/src/ch01-03-hello-cargo.md +++ b/src/ch01-03-hello-cargo.md @@ -188,8 +188,9 @@ build` when they’re ready to use the executable. Let’s recap what we’ve learned so far about Cargo: -* We can build a project using `cargo build` or `cargo check`. +* We can build a project using `cargo build`. * We can build and run a project in one step using `cargo run`. +* We can build a project without producing a binary to check for errors using `cargo check`. * Instead of saving the result of the build in the same directory as our code, Cargo stores it in the *target/debug* directory. diff --git a/src/ch06-02-match.md b/src/ch06-02-match.md index 06d8d6233f..5110c0d128 100644 --- a/src/ch06-02-match.md +++ b/src/ch06-02-match.md @@ -204,7 +204,7 @@ list before the `_` placeholder. However, the `match` expression can be a bit wordy in a situation in which we care about only *one* of the cases. For this situation, Rust provides `if let`. -More about patterns, and matching can be found in [chapter 18][ch18-00-patterns]. +More about patterns and matching can be found in [chapter 18][ch18-00-patterns]. [ch18-00-patterns]: ch18-00-patterns.html diff --git a/src/ch08-01-vectors.md b/src/ch08-01-vectors.md index 7df92724de..582f173bf1 100644 --- a/src/ch08-01-vectors.md +++ b/src/ch08-01-vectors.md @@ -138,7 +138,7 @@ and any other references to the contents of the vector remain valid. Recall the rule that states you can’t have mutable and immutable references in the same scope. That rule applies in Listing 8-7, where we hold an immutable reference to the first element in a vector and try to add an element to the end, which won’t -work. +work if we also try to refer to that element later in the function: ```rust,ignore,does_not_compile {{#rustdoc_include ../listings/ch08-common-collections/listing-08-07/src/main.rs:here}} diff --git a/src/ch10-01-syntax.md b/src/ch10-01-syntax.md index 0828c253b3..f50adf3462 100644 --- a/src/ch10-01-syntax.md +++ b/src/ch10-01-syntax.md @@ -44,12 +44,13 @@ to declare the type parameter name before we use it. To define the generic between the name of the function and the parameter list, like this: ```rust,ignore -fn largest(list: &[T]) -> T { +fn largest(list: &[T]) -> &T { ``` We read this definition as: the function `largest` is generic over some type `T`. This function has one parameter named `list`, which is a slice of values -of type `T`. The `largest` function will return a value of the same type `T`. +of type `T`. The `largest` function will return a reference to a value of the +same type `T`. Listing 10-5 shows the combined `largest` function definition using the generic data type in its signature. The listing also shows how we can call the function diff --git a/src/ch10-03-lifetime-syntax.md b/src/ch10-03-lifetime-syntax.md index 547d59963a..6cec3799e1 100644 --- a/src/ch10-03-lifetime-syntax.md +++ b/src/ch10-03-lifetime-syntax.md @@ -113,13 +113,10 @@ function to find the longer of two string slices Note that we want the function to take string slices, which are references, because we don’t want the `longest` function to take ownership of its -parameters. We want to allow the function to accept slices of a `String` (the -type stored in the variable `string1`) as well as string literals (which is -what variable `string2` contains). - -Refer to the [“String Slices as Parameters”][string-slices-as-parameters] section in Chapter 4 for more discussion about why the parameters we -use in Listing 10-20 are the ones we want. +parameters. Refer to the [“String Slices as +Parameters”][string-slices-as-parameters] section in Chapter 4 +for more discussion about why the parameters we use in Listing 10-20 are the +ones we want. If we try to implement the `longest` function as shown in Listing 10-21, it won’t compile. @@ -609,11 +606,13 @@ analysis happens at compile time, which doesn’t affect runtime performance! Believe it or not, there is much more to learn on the topics we discussed in this chapter: Chapter 17 discusses trait objects, which are another way to use -traits. Chapter 19 covers more complex scenarios involving lifetime annotations -as well as some advanced type system features. But next, you’ll learn how to -write tests in Rust so you can make sure your code is working the way it should. +traits. There are also more complex scenarios involving lifetime annotations +that you will only need in very advanced scenarios; for those, you should read +the [Rust Reference][reference]. But next, you’ll learn how to write tests in +Rust so you can make sure your code is working the way it should. [references-and-borrowing]: ch04-02-references-and-borrowing.html#references-and-borrowing [string-slices-as-parameters]: ch04-03-slices.html#string-slices-as-parameters +[reference]: ../reference/index.html diff --git a/src/ch12-05-working-with-environment-variables.md b/src/ch12-05-working-with-environment-variables.md index 89c455fcc7..d6ac076ebc 100644 --- a/src/ch12-05-working-with-environment-variables.md +++ b/src/ch12-05-working-with-environment-variables.md @@ -60,7 +60,10 @@ function to lowercase the query and the line before comparing them First, we lowercase the `query` string and store it in a shadowed variable with the same name. Calling `to_lowercase` on the query is necessary so no matter whether the user’s query is `"rust"`, `"RUST"`, `"Rust"`, or `"rUsT"`, we’ll -treat the query as if it were `"rust"` and be insensitive to the case. +treat the query as if it were `"rust"` and be insensitive to the case. While +`to_lowercase` will handle basic Unicode, it won't be 100% accurate. If we were +writing a real application, we'd want to do a bit more work here, but this section +is about environment variables, not Unicode, so we'll leave it at that here. Note that `query` is now a `String` rather than a string slice, because calling `to_lowercase` creates new data rather than referencing existing data. Say the @@ -154,12 +157,18 @@ the word “to” in all lowercase: Looks like that still works! Now, let’s run the program with `CASE_INSENSITIVE` set to `1` but with the same query `to`. -If you’re using PowerShell, you will need to set the environment variable and -run the program in two commands rather than one: +If you're using PowerShell, you will need to set the environment +variable and run the program as separate commands: ```console -$ $env:CASE_INSENSITIVE=1 -$ cargo run to poem.txt +PS> $Env:CASE_INSENSITIVE=1; cargo run to poem.txt +``` + +This will make `CASE_INSENSITIVE` persist for the remainder of your shell +session. It can be unset with the `Remove-Item` cmdlet: + +```console +PS> Remove-Item Env:CASE_INSENSITIVE ``` We should get lines that contain “to” that might have uppercase letters: diff --git a/src/ch14-03-cargo-workspaces.md b/src/ch14-03-cargo-workspaces.md index 64f7bb38a3..13ea37769c 100644 --- a/src/ch14-03-cargo-workspaces.md +++ b/src/ch14-03-cargo-workspaces.md @@ -28,7 +28,8 @@ Next, in the *add* directory, we create the *Cargo.toml* file that will configure the entire workspace. This file won’t have a `[package]` section or the metadata we’ve seen in other *Cargo.toml* files. Instead, it will start with a `[workspace]` section that will allow us to add members to the workspace -by specifying the path to our binary crate; in this case, that path is *adder*: +by specifying the path to the package with our binary crate; in this case, +that path is *adder*: Filename: Cargo.toml @@ -65,7 +66,7 @@ in your *add* directory should look like this: ``` The workspace has one *target* directory at the top level for the compiled -artifacts to be placed into; the `adder` crate doesn’t have its own *target* +artifacts to be placed into; the `adder` package doesn’t have its own *target* directory. Even if we were to run `cargo build` from inside the *adder* directory, the compiled artifacts would still end up in *add/target* rather than *add/adder/target*. Cargo structures the *target* directory in a workspace @@ -75,9 +76,9 @@ recompile each of the other crates in the workspace to have the artifacts in its own *target* directory. By sharing one *target* directory, the crates can avoid unnecessary rebuilding. -### Creating the Second Crate in the Workspace +### Creating the Second Package in the Workspace -Next, let’s create another member crate in the workspace and call it `add-one`. +Next, let’s create another member package in the workspace and call it `add-one`. Change the top-level *Cargo.toml* to specify the *add-one* path in the `members` list: @@ -125,9 +126,10 @@ In the *add-one/src/lib.rs* file, let’s add an `add_one` function: {{#rustdoc_include ../listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/add-one/src/lib.rs}} ``` -Now that we have a library crate in the workspace, we can have the binary crate -`adder` depend on the library crate `add-one`. First, we’ll need to add a path -dependency on `add-one` to *adder/Cargo.toml*. +Now that we have another package in the workspace, we can have the `adder` +package with our binary depend on the `add-one` package, that has our +library. First, we’ll need to add a path dependency on `add-one` to +*adder/Cargo.toml*. Filename: adder/Cargo.toml @@ -149,8 +151,8 @@ function to call the `add_one` function, as in Listing 14-7. {{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-07/add/adder/src/main.rs}} ``` -Listing 14-7: Using the `add-one` library crate from the -`adder` crate +Listing 14-7: Using the `add-one` library crate from the + `adder` crate Let’s build the workspace by running `cargo build` in the top-level *add* directory! @@ -168,8 +170,8 @@ $ cargo build Finished dev [unoptimized + debuginfo] target(s) in 0.68s ``` -To run the binary crate from the *add* directory, we need to specify which -package in the workspace we want to use by using the `-p` argument and the +To run the binary crate from the *add* directory, we can specify which +package in the workspace we want to run by using the `-p` argument and the package name with `cargo run`: