From 15d3172a311ea8b443deb230515fcba8df265bbe Mon Sep 17 00:00:00 2001 From: Martin Geisler Date: Mon, 16 Oct 2023 10:12:53 +0200 Subject: [PATCH] da: refresh translation and fix fuzzy entries (#1264) There are two commits, I hope they're individually small enough that GitHub will show them. --- po/da.po | 3375 +++++++++++++----------------------------------------- 1 file changed, 775 insertions(+), 2600 deletions(-) diff --git a/po/da.po b/po/da.po index f2ff4e63..3ef2a55c 100644 --- a/po/da.po +++ b/po/da.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: Comprehensive Rust 🦀\n" -"POT-Creation-Date: 2023-09-24\n" +"POT-Creation-Date: 2023-09-27T15:38:21+02:00\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -223,7 +223,7 @@ msgstr "while let udtryk" msgid "match expressions" msgstr "match udtryk" -#: src/SUMMARY.md:65 src/pattern-matching.md:1 +#: src/SUMMARY.md:65 src/SUMMARY.md:73 src/pattern-matching.md:1 msgid "Pattern Matching" msgstr "Mønstergenkendelse" @@ -248,10 +248,6 @@ msgstr "" msgid "Luhn Algorithm" msgstr "Luhn-algorithmen" -#: src/SUMMARY.md:73 -msgid "Pattern Matching (TBD)" -msgstr "Mønstergenkendelse (mangler)" - #: src/SUMMARY.md:75 msgid "Day 2: Morning" msgstr "Dag 2: Formiddag" @@ -354,6 +350,7 @@ msgid "Storing Books" msgstr "Lagring af bøger" #: src/SUMMARY.md:107 src/exercises/day-2/health-statistics.md:1 +#: src/exercises/day-2/solutions-morning.md:151 msgid "Health Statistics" msgstr "" @@ -511,7 +508,7 @@ msgstr "" msgid "A Simple GUI Library" msgstr "" -#: src/SUMMARY.md:156 src/exercises/day-3/solutions-morning.md:175 +#: src/SUMMARY.md:156 src/exercises/day-3/solutions-morning.md:145 msgid "Points and Polygons" msgstr "Punkter og polygoner" @@ -963,7 +960,7 @@ msgid "Cancellation" msgstr "Annulering" #: src/SUMMARY.md:305 src/exercises/concurrency/chat-app.md:1 -#: src/exercises/concurrency/solutions-afternoon.md:119 +#: src/exercises/concurrency/solutions-afternoon.md:95 msgid "Broadcast Chat Application" msgstr "Broadcast chat-applikation" @@ -1372,22 +1369,6 @@ msgid "" "with them:" msgstr "" -#: src/running-the-course/course-structure.md:57 -msgid "" -"```shell\n" -"cargo init concurrency\n" -"cd concurrency\n" -"cargo add tokio --features full\n" -"cargo run\n" -"```" -msgstr "" -"```shell\n" -"cargo init concurrency\n" -"cd concurrency\n" -"cargo add tokio --features full\n" -"cargo run\n" -"```" - #: src/running-the-course/course-structure.md:64 msgid "Format" msgstr "" @@ -1444,58 +1425,81 @@ msgstr "" msgid "" "[Brazilian Portuguese](https://google.github.io/comprehensive-rust/pt-BR/) " "by [@rastringer](https://github.com/rastringer), [@hugojacob](https://github." -"com/hugojacob), [@joaovicmendes](https://github.com/joaovicmendes) and " +"com/hugojacob), [@joaovicmendes](https://github.com/joaovicmendes), and " "[@henrif75](https://github.com/henrif75)." msgstr "" #: src/running-the-course/translations.md:7 msgid "" "[Korean](https://google.github.io/comprehensive-rust/ko/) by [@keispace]" -"(https://github.com/keispace), [@jiyongp](https://github.com/jiyongp) and " +"(https://github.com/keispace), [@jiyongp](https://github.com/jiyongp), and " "[@jooyunghan](https://github.com/jooyunghan)." msgstr "" -#: src/running-the-course/translations.md:9 +#: src/running-the-course/translations.md:8 +msgid "" +"[Spanish](https://google.github.io/comprehensive-rust/es/) by [@deavid]" +"(https://github.com/deavid)." +msgstr "" + +#: src/running-the-course/translations.md:10 msgid "" "Use the language picker in the top-right corner to switch between languages." msgstr "" -#: src/running-the-course/translations.md:11 +#: src/running-the-course/translations.md:12 msgid "Incomplete Translations" msgstr "Ufuldstændige oversættelser" -#: src/running-the-course/translations.md:13 +#: src/running-the-course/translations.md:14 msgid "" "There is a large number of in-progress translations. We link to the most " "recently updated translations:" msgstr "" -#: src/running-the-course/translations.md:16 +#: src/running-the-course/translations.md:17 msgid "" "[Bengali](https://google.github.io/comprehensive-rust/bn/) by [@raselmandol]" "(https://github.com/raselmandol)." msgstr "" -#: src/running-the-course/translations.md:17 +#: src/running-the-course/translations.md:18 +msgid "" +"[Chinese (Traditional)](https://google.github.io/comprehensive-rust/zh-TW/) " +"by [@hueich](https://github.com/hueich), [@victorhsieh](https://github.com/" +"victorhsieh), [@mingyc](https://github.com/mingyc), and [@johnathan79717]" +"(https://github.com/johnathan79717)." +msgstr "" + +#: src/running-the-course/translations.md:19 +msgid "" +"[Chinese (Simplified)](https://google.github.io/comprehensive-rust/zh-CN/) " +"by [@suetfei](https://github.com/suetfei), [@wnghl](https://github.com/" +"wnghl), [@anlunx](https://github.com/anlunx), [@kongy](https://github.com/" +"kongy), [@noahdragon](https://github.com/noahdragon), and [@superwhd]" +"(https://github.com/superwhd)." +msgstr "" + +#: src/running-the-course/translations.md:20 msgid "" "[French](https://google.github.io/comprehensive-rust/fr/) by [@KookaS]" "(https://github.com/KookaS) and [@vcaen](https://github.com/vcaen)." msgstr "" -#: src/running-the-course/translations.md:18 +#: src/running-the-course/translations.md:21 msgid "" "[German](https://google.github.io/comprehensive-rust/de/) by [@Throvn]" "(https://github.com/Throvn) and [@ronaldfw](https://github.com/ronaldfw)." msgstr "" -#: src/running-the-course/translations.md:19 +#: src/running-the-course/translations.md:22 msgid "" "[Japanese](https://google.github.io/comprehensive-rust/ja/) by [@CoinEZ-JPN]" "(https://github.com/CoinEZ) and [@momotaro1105](https://github.com/" "momotaro1105)." msgstr "" -#: src/running-the-course/translations.md:21 +#: src/running-the-course/translations.md:24 msgid "" "If you want to help with this effort, please see [our instructions](https://" "github.com/google/comprehensive-rust/blob/main/TRANSLATIONS.md) for how to " @@ -1524,10 +1528,21 @@ msgstr "" msgid "" "This will give you the Cargo build tool (`cargo`) and the Rust compiler " "(`rustc`). You will also get `rustup`, a command line utility that you can " -"use to install/switch toolchains, setup cross compilation, etc." +"use to install to different compiler versions." msgstr "" -#: src/cargo.md:16 +#: src/cargo.md:14 +msgid "" +"After installing Rust, you should configure your editor or IDE to work with " +"Rust. Most editors do this by talking to [rust-analyzer](https://rust-" +"analyzer.github.io/), which provides auto-completion and jump-to-definition " +"functionality for [VS Code](https://code.visualstudio.com/), [Emacs](https://" +"rust-analyzer.github.io/manual.html#emacs), [Vim/Neovim](https://rust-" +"analyzer.github.io/manual.html#vimneovim), and many others. There is also a " +"different IDE available called [RustRover](https://www.jetbrains.com/rust/)." +msgstr "" + +#: src/cargo.md:18 msgid "" "On Debian/Ubuntu, you can also install Cargo, the Rust source and the [Rust " "formatter](https://github.com/rust-lang/rustfmt) via `apt`. However, this " @@ -1535,32 +1550,6 @@ msgid "" "command would be:" msgstr "" -#: src/cargo.md:18 -msgid "" -"```shell\n" -"sudo apt install cargo rust-src rustfmt\n" -"```" -msgstr "" -"```shell\n" -"sudo apt install cargo rust-src rustfmt\n" -"```" - -#: src/cargo.md:22 -msgid "" -"We suggest using [VS Code](https://code.visualstudio.com/) to edit the code " -"(but any LSP compatible editor works with rust-analyzer[3](https://rust-" -"analyzer.github.io/))." -msgstr "" - -#: src/cargo.md:24 -msgid "" -"Some folks also like to use the [JetBrains](https://www.jetbrains.com/" -"clion/) family of IDEs, which do their own analysis but have their own " -"tradeoffs. If you prefer them, you can install the [Rust Plugin](https://www." -"jetbrains.com/rust/). Please take note that as of January 2023 debugging " -"only works on the CLion version of the JetBrains IDEA suite." -msgstr "" - #: src/cargo/rust-ecosystem.md:1 msgid "The Rust Ecosystem" msgstr "" @@ -1595,8 +1584,8 @@ msgstr "" #: src/cargo/rust-ecosystem.md:21 src/hello-world.md:25 #: src/hello-world/small-example.md:27 src/why-rust/runtime.md:10 -#: src/why-rust/modern.md:21 src/basic-syntax/compound-types.md:30 -#: src/basic-syntax/references.md:23 +#: src/why-rust/modern.md:21 src/basic-syntax/compound-types.md:32 +#: src/basic-syntax/references.md:24 #: src/pattern-matching/destructuring-enums.md:35 #: src/ownership/double-free-modern-cpp.md:55 #: src/error-handling/try-operator.md:48 @@ -1777,22 +1766,6 @@ msgid "" "latest stable Rust release has these version numbers:" msgstr "" -#: src/cargo/running-locally.md:8 -msgid "" -"```shell\n" -"% rustc --version\n" -"rustc 1.69.0 (84c898d65 2023-04-16)\n" -"% cargo --version\n" -"cargo 1.69.0 (6e9a83356 2023-04-12)\n" -"```" -msgstr "" -"```shell\n" -"% rustc --version\n" -"rustc 1.69.0 (84c898d65 2023-04-16)\n" -"% cargo --version\n" -"cargo 1.69.0 (6e9a83356 2023-04-12)\n" -"```" - #: src/cargo/running-locally.md:15 msgid "" "You can use any later version too since Rust maintains backwards " @@ -1814,43 +1787,11 @@ msgid "" "Use `cargo new exercise` to create a new `exercise/` directory for your code:" msgstr "" -#: src/cargo/running-locally.md:24 -msgid "" -"```shell\n" -"$ cargo new exercise\n" -" Created binary (application) `exercise` package\n" -"```" -msgstr "" -"```shell\n" -"$ cargo new exercise\n" -" Created binary (application) `exercise` package\n" -"```" - #: src/cargo/running-locally.md:29 msgid "" "Navigate into `exercise/` and use `cargo run` to build and run your binary:" msgstr "" -#: src/cargo/running-locally.md:31 -msgid "" -"```shell\n" -"$ cd exercise\n" -"$ cargo run\n" -" Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n" -" Finished dev [unoptimized + debuginfo] target(s) in 0.75s\n" -" Running `target/debug/exercise`\n" -"Hello, world!\n" -"```" -msgstr "" -"```shell\n" -"$ cd exercise\n" -"$ cargo run\n" -" Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n" -" Finished dev [unoptimized + debuginfo] target(s) in 0.75s\n" -" Running `target/debug/exercise`\n" -"Hello, world!\n" -"```" - #: src/cargo/running-locally.md:40 msgid "" "Replace the boiler-plate code in `src/main.rs` with your own code. For " @@ -1875,24 +1816,6 @@ msgstr "" msgid "Use `cargo run` to build and run your updated binary:" msgstr "" -#: src/cargo/running-locally.md:51 -msgid "" -"```shell\n" -"$ cargo run\n" -" Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n" -" Finished dev [unoptimized + debuginfo] target(s) in 0.24s\n" -" Running `target/debug/exercise`\n" -"Edit me!\n" -"```" -msgstr "" -"```shell\n" -"$ cargo run\n" -" Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n" -" Finished dev [unoptimized + debuginfo] target(s) in 0.24s\n" -" Running `target/debug/exercise`\n" -"Redigér mig!\n" -"```" - #: src/cargo/running-locally.md:59 msgid "" "Use `cargo check` to quickly check your project for errors, use `cargo " @@ -2621,43 +2544,11 @@ msgid "" "amount of `#` on either side of the quotes:" msgstr "" -#: src/basic-syntax/scalar-types.md:27 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" println!(r#\"link\"#);\n" -" println!(\"link\");\n" -"}\n" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" println!(r#\"link\"#);\n" -" println!(\"link\");\n" -"}\n" -"```" - -#: src/basic-syntax/scalar-types.md:34 +#: src/basic-syntax/scalar-types.md:35 msgid "Byte strings allow you to create a `&[u8]` value directly:" msgstr "" -#: src/basic-syntax/scalar-types.md:36 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" println!(\"{:?}\", b\"abc\");\n" -" println!(\"{:?}\", &[97, 98, 99]);\n" -"}\n" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" println!(\"{:?}\", b\"abc\");\n" -" println!(\"{:?}\", &[97, 98, 99]);\n" -"}\n" -"```" - -#: src/basic-syntax/scalar-types.md:43 +#: src/basic-syntax/scalar-types.md:45 msgid "" "All underscores in numbers can be left out, they are for legibility only. So " "`1_000` can be written as `1000` (or `10_00`), and `123_i64` can be written " @@ -2692,51 +2583,15 @@ msgstr "" msgid "Array assignment and access:" msgstr "" -#: src/basic-syntax/compound-types.md:10 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let mut a: [i8; 10] = [42; 10];\n" -" a[5] = 0;\n" -" println!(\"a: {:?}\", a);\n" -"}\n" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" let mut a: [i8; 10] = [42; 10];\n" -" a[5] = 0;\n" -" println!(\"a: {:?}\", a);\n" -"}\n" -"```" - -#: src/basic-syntax/compound-types.md:18 +#: src/basic-syntax/compound-types.md:19 msgid "Tuple assignment and access:" msgstr "" -#: src/basic-syntax/compound-types.md:20 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let t: (i8, bool) = (7, true);\n" -" println!(\"1st index: {}\", t.0);\n" -" println!(\"2nd index: {}\", t.1);\n" -"}\n" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" let t: (i8, bool) = (7, true);\n" -" println!(\"1. indeks: {}\", t.0);\n" -" println!(\"2. indeks: {}\", t.1);\n" -"}\n" -"```" - -#: src/basic-syntax/compound-types.md:32 +#: src/basic-syntax/compound-types.md:34 msgid "Arrays:" msgstr "" -#: src/basic-syntax/compound-types.md:34 +#: src/basic-syntax/compound-types.md:36 msgid "" "A value of the array type `[T; N]` holds `N` (a compile-time constant) " "elements of the same type `T`. Note that the length of the array is _part of " @@ -2744,11 +2599,11 @@ msgid "" "different types." msgstr "" -#: src/basic-syntax/compound-types.md:38 +#: src/basic-syntax/compound-types.md:40 msgid "We can use literals to assign values to arrays." msgstr "" -#: src/basic-syntax/compound-types.md:40 +#: src/basic-syntax/compound-types.md:42 msgid "" "In the main function, the print statement asks for the debug implementation " "with the `?` format parameter: `{}` gives the default output, `{:?}` gives " @@ -2756,31 +2611,31 @@ msgid "" "specifying the value after the format string." msgstr "" -#: src/basic-syntax/compound-types.md:45 +#: src/basic-syntax/compound-types.md:47 msgid "" "Adding `#`, eg `{a:#?}`, invokes a \"pretty printing\" format, which can be " "easier to read." msgstr "" -#: src/basic-syntax/compound-types.md:47 +#: src/basic-syntax/compound-types.md:49 msgid "Tuples:" msgstr "" -#: src/basic-syntax/compound-types.md:49 +#: src/basic-syntax/compound-types.md:51 msgid "Like arrays, tuples have a fixed length." msgstr "" -#: src/basic-syntax/compound-types.md:51 +#: src/basic-syntax/compound-types.md:53 msgid "Tuples group together values of different types into a compound type." msgstr "" -#: src/basic-syntax/compound-types.md:53 +#: src/basic-syntax/compound-types.md:55 msgid "" "Fields of a tuple can be accessed by the period and the index of the value, " "e.g. `t.0`, `t.1`." msgstr "" -#: src/basic-syntax/compound-types.md:55 +#: src/basic-syntax/compound-types.md:57 msgid "" "The empty tuple `()` is also known as the \"unit type\". It is both a type, " "and the only valid value of that type - that is to say both the type and its " @@ -2788,7 +2643,7 @@ msgid "" "function or expression has no return value, as we'll see in a future slide. " msgstr "" -#: src/basic-syntax/compound-types.md:59 +#: src/basic-syntax/compound-types.md:61 msgid "" "You can think of it as `void` that can be familiar to you from other " "programming languages." @@ -2798,49 +2653,29 @@ msgstr "" msgid "Like C++, Rust has references:" msgstr "" -#: src/basic-syntax/references.md:5 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let mut x: i32 = 10;\n" -" let ref_x: &mut i32 = &mut x;\n" -" *ref_x = 20;\n" -" println!(\"x: {x}\");\n" -"}\n" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" let mut x: i32 = 10;\n" -" let ref_x: &mut i32 = &mut x;\n" -" *ref_x = 20;\n" -" println!(\"x: {x}\");\n" -"}\n" -"```" - -#: src/basic-syntax/references.md:14 +#: src/basic-syntax/references.md:15 msgid "Some notes:" msgstr "" -#: src/basic-syntax/references.md:16 +#: src/basic-syntax/references.md:17 msgid "" "We must dereference `ref_x` when assigning to it, similar to C and C++ " "pointers." msgstr "" -#: src/basic-syntax/references.md:17 +#: src/basic-syntax/references.md:18 msgid "" "Rust will auto-dereference in some cases, in particular when invoking " "methods (try `ref_x.count_ones()`)." msgstr "" -#: src/basic-syntax/references.md:19 +#: src/basic-syntax/references.md:20 msgid "" "References that are declared as `mut` can be bound to different values over " "their lifetime." msgstr "" -#: src/basic-syntax/references.md:25 +#: src/basic-syntax/references.md:26 msgid "" "Be sure to note the difference between `let mut ref_x: &i32` and `let ref_x: " "&mut i32`. The first one represents a mutable reference which can be bound " @@ -2852,41 +2687,17 @@ msgstr "" msgid "Rust will statically forbid dangling references:" msgstr "" -#: src/basic-syntax/references-dangling.md:5 -msgid "" -"```rust,editable,compile_fail\n" -"fn main() {\n" -" let ref_x: &i32;\n" -" {\n" -" let x: i32 = 10;\n" -" ref_x = &x;\n" -" }\n" -" println!(\"ref_x: {ref_x}\");\n" -"}\n" -"```" -msgstr "" -"```rust,editable,compile_fail\n" -"fn main() {\n" -" let ref_x: &i32;\n" -" {\n" -" let x: i32 = 10;\n" -" ref_x = &x;\n" -" }\n" -" println!(\"ref_x: {ref_x}\");\n" -"}\n" -"```" - -#: src/basic-syntax/references-dangling.md:16 +#: src/basic-syntax/references-dangling.md:17 msgid "A reference is said to \"borrow\" the value it refers to." msgstr "" -#: src/basic-syntax/references-dangling.md:17 +#: src/basic-syntax/references-dangling.md:18 msgid "" "Rust is tracking the lifetimes of all references to ensure they live long " "enough." msgstr "" -#: src/basic-syntax/references-dangling.md:19 +#: src/basic-syntax/references-dangling.md:20 msgid "We will talk more about borrowing when we get to ownership." msgstr "" @@ -2894,76 +2705,52 @@ msgstr "" msgid "A slice gives you a view into a larger collection:" msgstr "" -#: src/basic-syntax/slices.md:5 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let mut a: [i32; 6] = [10, 20, 30, 40, 50, 60];\n" -" println!(\"a: {a:?}\");\n" -"\n" -" let s: &[i32] = &a[2..4];\n" -"\n" -" println!(\"s: {s:?}\");\n" -"}\n" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" let mut a: [i32; 6] = [10, 20, 30, 40, 50, 60];\n" -" println!(\"a: {a:?}\");\n" -"\n" -" let s: &[i32] = &a[2..4];\n" -"\n" -" println!(\"s: {s:?}\");\n" -"}\n" -"```" - -#: src/basic-syntax/slices.md:16 +#: src/basic-syntax/slices.md:17 msgid "Slices borrow data from the sliced type." msgstr "" -#: src/basic-syntax/slices.md:17 +#: src/basic-syntax/slices.md:18 msgid "Question: What happens if you modify `a[3]` right before printing `s`?" msgstr "" -#: src/basic-syntax/slices.md:21 +#: src/basic-syntax/slices.md:22 msgid "" "We create a slice by borrowing `a` and specifying the starting and ending " "indexes in brackets." msgstr "" -#: src/basic-syntax/slices.md:23 +#: src/basic-syntax/slices.md:24 msgid "" "If the slice starts at index 0, Rust’s range syntax allows us to drop the " "starting index, meaning that `&a[0..a.len()]` and `&a[..a.len()]` are " "identical." msgstr "" -#: src/basic-syntax/slices.md:25 +#: src/basic-syntax/slices.md:26 msgid "" "The same is true for the last index, so `&a[2..a.len()]` and `&a[2..]` are " "identical." msgstr "" -#: src/basic-syntax/slices.md:27 +#: src/basic-syntax/slices.md:28 msgid "" "To easily create a slice of the full array, we can therefore use `&a[..]`." msgstr "" -#: src/basic-syntax/slices.md:29 +#: src/basic-syntax/slices.md:30 msgid "" "`s` is a reference to a slice of `i32`s. Notice that the type of `s` " "(`&[i32]`) no longer mentions the array length. This allows us to perform " "computation on slices of different sizes." msgstr "" -#: src/basic-syntax/slices.md:31 +#: src/basic-syntax/slices.md:32 msgid "" "Slices always borrow from another object. In this example, `a` has to remain " "'alive' (in scope) for at least as long as our slice. " msgstr "" -#: src/basic-syntax/slices.md:33 +#: src/basic-syntax/slices.md:34 msgid "" "The question about modifying `a[3]` can spark an interesting discussion, but " "the answer is that for memory safety reasons you cannot do it through `a` at " @@ -3071,89 +2858,31 @@ msgid "" "Fizz_buzz) interview question:" msgstr "" -#: src/basic-syntax/functions.md:5 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" print_fizzbuzz_to(20);\n" -"}\n" -"\n" -"fn is_divisible(n: u32, divisor: u32) -> bool {\n" -" if divisor == 0 {\n" -" return false;\n" -" }\n" -" n % divisor == 0\n" -"}\n" -"\n" -"fn fizzbuzz(n: u32) -> String {\n" -" let fizz = if is_divisible(n, 3) { \"fizz\" } else { \"\" };\n" -" let buzz = if is_divisible(n, 5) { \"buzz\" } else { \"\" };\n" -" if fizz.is_empty() && buzz.is_empty() {\n" -" return format!(\"{n}\");\n" -" }\n" -" format!(\"{fizz}{buzz}\")\n" -"}\n" -"\n" -"fn print_fizzbuzz_to(n: u32) {\n" -" for i in 1..=n {\n" -" println!(\"{}\", fizzbuzz(i));\n" -" }\n" -"}\n" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" print_fizzbuzz_to(20);\n" -"}\n" -"\n" -"fn is_divisible(n: u32, divisor: u32) -> bool {\n" -" if divisor == 0 {\n" -" return false;\n" -" }\n" -" n % divisor == 0\n" -"}\n" -"\n" -"fn fizzbuzz(n: u32) -> String {\n" -" let fizz = if is_divisible(n, 3) { \"fizz\" } else { \"\" };\n" -" let buzz = if is_divisible(n, 5) { \"buzz\" } else { \"\" };\n" -" if fizz.is_empty() && buzz.is_empty() {\n" -" return format!(\"{n}\");\n" -" }\n" -" format!(\"{fizz}{buzz}\")\n" -"}\n" -"\n" -"fn print_fizzbuzz_to(n: u32) {\n" -" for i in 1..=n {\n" -" println!(\"{}\", fizzbuzz(i));\n" -" }\n" -"}\n" -"```" - -#: src/basic-syntax/functions.md:35 +#: src/basic-syntax/functions.md:36 msgid "" "We refer in `main` to a function written below. Neither forward declarations " "nor headers are necessary. " msgstr "" -#: src/basic-syntax/functions.md:36 +#: src/basic-syntax/functions.md:37 msgid "" "Declaration parameters are followed by a type (the reverse of some " "programming languages), then a return type." msgstr "" -#: src/basic-syntax/functions.md:37 +#: src/basic-syntax/functions.md:38 msgid "" "The last expression in a function body (or any block) becomes the return " "value. Simply omit the `;` at the end of the expression." msgstr "" -#: src/basic-syntax/functions.md:38 +#: src/basic-syntax/functions.md:39 msgid "" "Some functions have no return value, and return the 'unit type', `()`. The " "compiler will infer this if the `-> ()` return type is omitted." msgstr "" -#: src/basic-syntax/functions.md:39 +#: src/basic-syntax/functions.md:40 msgid "" "The range expression in the `for` loop in `print_fizzbuzz_to()` contains " "`=n`, which causes it to include the upper bound." @@ -3280,20 +3009,6 @@ msgstr "" msgid "Add a static method called `Rectangle::new` and call this from `main`:" msgstr "" -#: src/basic-syntax/methods.md:36 -msgid "" -"```rust,editable,compile_fail\n" -"fn new(width: u32, height: u32) -> Rectangle {\n" -" Rectangle { width, height }\n" -"}\n" -"```" -msgstr "" -"```rust,editable,compile_fail\n" -"fn new(width: u32, height: u32) -> Rectangle {\n" -" Rectangle { width, height }\n" -"}\n" -"```" - #: src/basic-syntax/methods.md:42 msgid "" "While _technically_, Rust does not have custom constructors, static methods " @@ -3427,35 +3142,7 @@ msgid "" "implicit_conversion)). You can see this in a program like this:" msgstr "" -#: src/exercises/day-1/implicit-conversions.md:6 -msgid "" -"```rust,editable,compile_fail\n" -"fn multiply(x: i16, y: i16) -> i16 {\n" -" x * y\n" -"}\n" -"\n" -"fn main() {\n" -" let x: i8 = 15;\n" -" let y: i16 = 1000;\n" -"\n" -" println!(\"{x} * {y} = {}\", multiply(x, y));\n" -"}\n" -"```" -msgstr "" -"```rust,editable,compile_fail\n" -"fn multiply(x: i16, y: i16) -> i16 {\n" -" x * y\n" -"}\n" -"\n" -"fn main() {\n" -" let x: i8 = 15;\n" -" let y: i16 = 1000;\n" -"\n" -" println!(\"{x} * {y} = {}\", multiply(x, y));\n" -"}\n" -"```" - -#: src/exercises/day-1/implicit-conversions.md:19 +#: src/exercises/day-1/implicit-conversions.md:20 msgid "" "The Rust integer types all implement the [`From`](https://doc.rust-lang." "org/std/convert/trait.From.html) and [`Into`](https://doc.rust-lang.org/" @@ -3465,7 +3152,7 @@ msgid "" "expresses that it can be converted into another type." msgstr "" -#: src/exercises/day-1/implicit-conversions.md:25 +#: src/exercises/day-1/implicit-conversions.md:26 msgid "" "The standard library has an implementation of `From for i16`, which " "means that we can convert a variable `x` of type `i8` to an `i16` by " @@ -3474,22 +3161,22 @@ msgid "" "i8`." msgstr "" -#: src/exercises/day-1/implicit-conversions.md:30 +#: src/exercises/day-1/implicit-conversions.md:31 msgid "" "The same applies for your own `From` implementations for your own types, so " "it is sufficient to only implement `From` to get a respective `Into` " "implementation automatically." msgstr "" -#: src/exercises/day-1/implicit-conversions.md:33 +#: src/exercises/day-1/implicit-conversions.md:34 msgid "Execute the above program and look at the compiler error." msgstr "" -#: src/exercises/day-1/implicit-conversions.md:35 +#: src/exercises/day-1/implicit-conversions.md:36 msgid "Update the code above to use `into()` to do the conversion." msgstr "" -#: src/exercises/day-1/implicit-conversions.md:37 +#: src/exercises/day-1/implicit-conversions.md:38 msgid "" "Change the types of `x` and `y` to other things (such as `f32`, `bool`, " "`i128`) to see which types you can convert to which other types. Try " @@ -3507,45 +3194,19 @@ msgstr "" msgid "We saw that an array can be declared like this:" msgstr "" -#: src/exercises/day-1/for-loops.md:5 -msgid "" -"```rust\n" -"let array = [10, 20, 30];\n" -"```" -msgstr "" -"```rust\n" -"let array = [10, 20, 30];\n" -"```" - #: src/exercises/day-1/for-loops.md:9 msgid "" "You can print such an array by asking for its debug representation with `{:?}" "`:" msgstr "" -#: src/exercises/day-1/for-loops.md:11 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let array = [10, 20, 30];\n" -" println!(\"array: {array:?}\");\n" -"}\n" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" let array = [10, 20, 30];\n" -" println!(\"array: {array:?}\");\n" -"}\n" -"```" - -#: src/exercises/day-1/for-loops.md:18 +#: src/exercises/day-1/for-loops.md:19 msgid "" "Rust lets you iterate over things like arrays and ranges using the `for` " "keyword:" msgstr "" -#: src/exercises/day-1/for-loops.md:21 +#: src/exercises/day-1/for-loops.md:22 msgid "" "```rust,editable\n" "fn main() {\n" @@ -3565,38 +3226,24 @@ msgid "" "```" msgstr "" -#: src/exercises/day-1/for-loops.md:38 +#: src/exercises/day-1/for-loops.md:39 msgid "" "Use the above to write a function `pretty_print` which pretty-print a matrix " "and a function `transpose` which will transpose a matrix (turn rows into " "columns):" msgstr "" -#: src/exercises/day-1/for-loops.md:41 -msgid "" -"```bob\n" -" ⎛⎡1 2 3⎤⎞ ⎡1 4 7⎤\n" -"\"transpose\"⎜⎢4 5 6⎥⎟ \"==\"⎢2 5 8⎥\n" -" ⎝⎣7 8 9⎦⎠ ⎣3 6 9⎦\n" -"```" -msgstr "" -"```bob\n" -" ⎛⎡1 2 3⎤⎞ ⎡1 4 7⎤\n" -"\"transpose\"⎜⎢4 5 6⎥⎟ \"==\"⎢2 5 8⎥\n" -" ⎝⎣7 8 9⎦⎠ ⎣3 6 9⎦\n" -"```" - -#: src/exercises/day-1/for-loops.md:47 +#: src/exercises/day-1/for-loops.md:49 msgid "Hard-code both functions to operate on 3 × 3 matrices." msgstr "" -#: src/exercises/day-1/for-loops.md:49 +#: src/exercises/day-1/for-loops.md:51 msgid "" "Copy the code below to and implement the " "functions:" msgstr "" -#: src/exercises/day-1/for-loops.md:52 +#: src/exercises/day-1/for-loops.md:54 msgid "" "```rust,should_panic\n" "// TODO: remove this when you're done with your implementation.\n" @@ -3627,47 +3274,47 @@ msgid "" "```" msgstr "" -#: src/exercises/day-1/for-loops.md:80 +#: src/exercises/day-1/for-loops.md:82 msgid "Bonus Question" msgstr "" -#: src/exercises/day-1/for-loops.md:82 +#: src/exercises/day-1/for-loops.md:84 msgid "" "Could you use `&[i32]` slices instead of hard-coded 3 × 3 matrices for your " "argument and return types? Something like `&[&[i32]]` for a two-dimensional " "slice-of-slices. Why or why not?" msgstr "" -#: src/exercises/day-1/for-loops.md:87 +#: src/exercises/day-1/for-loops.md:89 msgid "" "See the [`ndarray` crate](https://docs.rs/ndarray/) for a production quality " "implementation." msgstr "" -#: src/exercises/day-1/for-loops.md:92 +#: src/exercises/day-1/for-loops.md:94 msgid "" "The solution and the answer to the bonus section are available in the " "[Solution](solutions-morning.md#arrays-and-for-loops) section." msgstr "" -#: src/exercises/day-1/for-loops.md:95 +#: src/exercises/day-1/for-loops.md:97 msgid "" "The use of the reference `&array` within `for n in &array` is a subtle " "preview of issues of ownership that will come later in the afternoon." msgstr "" -#: src/exercises/day-1/for-loops.md:98 +#: src/exercises/day-1/for-loops.md:100 msgid "Without the `&`..." msgstr "" -#: src/exercises/day-1/for-loops.md:99 +#: src/exercises/day-1/for-loops.md:101 msgid "" "The loop would have been one that consumes the array. This is a change " "[introduced in the 2021 Edition](https://doc.rust-lang.org/edition-guide/" "rust-2021/IntoIterator-for-arrays.html)." msgstr "" -#: src/exercises/day-1/for-loops.md:102 +#: src/exercises/day-1/for-loops.md:104 msgid "" "An implicit array copy would have occurred. Since `i32` is a copy type, " "then `[i32; 3]` is also a copy type." @@ -3687,66 +3334,31 @@ msgid "" "and a type, which are those of the last expression of the block:" msgstr "" -#: src/control-flow/blocks.md:7 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let x = {\n" -" let y = 10;\n" -" println!(\"y: {y}\");\n" -" let z = {\n" -" let w = {\n" -" 3 + 4\n" -" };\n" -" println!(\"w: {w}\");\n" -" y * w\n" -" };\n" -" println!(\"z: {z}\");\n" -" z - y\n" -" };\n" -" println!(\"x: {x}\");\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/blocks.md:26 +#: src/control-flow/blocks.md:27 msgid "" "If the last expression ends with `;`, then the resulting value and type is " "`()`." msgstr "" -#: src/control-flow/blocks.md:28 +#: src/control-flow/blocks.md:29 msgid "" "The same rule is used for functions: the value of the function body is the " "return value:" msgstr "" -#: src/control-flow/blocks.md:31 -msgid "" -"```rust,editable\n" -"fn double(x: i32) -> i32 {\n" -" x + x\n" -"}\n" -"\n" -"fn main() {\n" -" println!(\"doubled: {}\", double(7));\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/blocks.md:43 src/enums.md:34 src/enums/sizes.md:28 +#: src/control-flow/blocks.md:45 src/enums.md:34 src/enums/sizes.md:28 #: src/pattern-matching.md:25 src/pattern-matching/match-guards.md:22 #: src/structs.md:31 src/methods.md:30 src/methods/example.md:46 msgid "Key Points:" msgstr "" -#: src/control-flow/blocks.md:44 +#: src/control-flow/blocks.md:46 msgid "" "The point of this slide is to show that blocks have a type and value in " "Rust. " msgstr "" -#: src/control-flow/blocks.md:45 +#: src/control-flow/blocks.md:47 msgid "" "You can show how the value of the block changes by changing the last line in " "the block. For instance, adding/removing a semicolon or using a `return`." @@ -3762,40 +3374,12 @@ msgid "" "if-expr.html#if-expressions) exactly like `if` statements in other languages:" msgstr "" -#: src/control-flow/if-expressions.md:7 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let mut x = 10;\n" -" if x % 2 == 0 {\n" -" x = x / 2;\n" -" } else {\n" -" x = 3 * x + 1;\n" -" }\n" -"}\n" -"```" -msgstr "" - #: src/control-flow/if-expressions.md:18 msgid "" "In addition, you can use `if` as an expression. The last expression of each " "block becomes the value of the `if` expression:" msgstr "" -#: src/control-flow/if-expressions.md:22 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let mut x = 10;\n" -" x = if x % 2 == 0 {\n" -" x / 2\n" -" } else {\n" -" 3 * x + 1\n" -" };\n" -"}\n" -"```" -msgstr "" - #: src/control-flow/if-expressions.md:35 msgid "" "Because `if` is an expression and must have a particular type, both of its " @@ -3814,42 +3398,25 @@ msgid "" "automatically call `into_iter()` on the expression and then iterate over it:" msgstr "" -#: src/control-flow/for-expressions.md:7 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let v = vec![10, 20, 30];\n" -"\n" -" for x in v {\n" -" println!(\"x: {x}\");\n" -" }\n" -" \n" -" for i in (0..10).step_by(2) {\n" -" println!(\"i: {i}\");\n" -" }\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/for-expressions.md:21 +#: src/control-flow/for-expressions.md:22 msgid "You can use `break` and `continue` here as usual." msgstr "" -#: src/control-flow/for-expressions.md:25 +#: src/control-flow/for-expressions.md:26 msgid "Index iteration is not a special syntax in Rust for just that case." msgstr "" -#: src/control-flow/for-expressions.md:26 +#: src/control-flow/for-expressions.md:27 msgid "`(0..10)` is a range that implements an `Iterator` trait. " msgstr "" -#: src/control-flow/for-expressions.md:27 +#: src/control-flow/for-expressions.md:28 msgid "" "`step_by` is a method that returns another `Iterator` that skips every other " "element. " msgstr "" -#: src/control-flow/for-expressions.md:28 +#: src/control-flow/for-expressions.md:29 msgid "" "Modify the elements in the vector and explain the compiler errors. Change " "vector `v` to be mutable and the for loop to `for x in v.iter_mut()`." @@ -3865,23 +3432,6 @@ msgid "" "expr.html#predicate-loops) works very similar to other languages:" msgstr "" -#: src/control-flow/while-expressions.md:6 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let mut x = 10;\n" -" while x != 1 {\n" -" x = if x % 2 == 0 {\n" -" x / 2\n" -" } else {\n" -" 3 * x + 1\n" -" };\n" -" }\n" -" println!(\"Final x: {x}\");\n" -"}\n" -"```" -msgstr "" - #: src/control-flow/break-continue.md:1 msgid "`break` and `continue`" msgstr "" @@ -3904,28 +3454,7 @@ msgid "" "used to break out of nested loops:" msgstr "" -#: src/control-flow/break-continue.md:10 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let v = vec![10, 20, 30];\n" -" let mut iter = v.into_iter();\n" -" 'outer: while let Some(x) = iter.next() {\n" -" println!(\"x: {x}\");\n" -" let mut i = 0;\n" -" while i < x {\n" -" println!(\"x: {x}, i: {i}\");\n" -" i += 1;\n" -" if i == 3 {\n" -" break 'outer;\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/break-continue.md:28 +#: src/control-flow/break-continue.md:29 msgid "" "In this case we break the outer loop after 3 iterations of the inner loop." msgstr "" @@ -3944,31 +3473,11 @@ msgstr "" msgid "Here you must either `break` or `return` to stop the loop:" msgstr "" -#: src/control-flow/loop-expressions.md:8 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let mut x = 10;\n" -" loop {\n" -" x = if x % 2 == 0 {\n" -" x / 2\n" -" } else {\n" -" 3 * x + 1\n" -" };\n" -" if x == 1 {\n" -" break;\n" -" }\n" -" }\n" -" println!(\"Final x: {x}\");\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/loop-expressions.md:27 +#: src/control-flow/loop-expressions.md:28 msgid "Break the `loop` with a value (e.g. `break 8`) and print it out." msgstr "" -#: src/control-flow/loop-expressions.md:28 +#: src/control-flow/loop-expressions.md:29 msgid "" "Note that `loop` is the only looping construct which returns a non-trivial " "value. This is because it's guaranteed to be entered at least once (unlike " @@ -3981,19 +3490,7 @@ msgid "" "by default:" msgstr "" -#: src/basic-syntax/variables.md:6 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let x: i32 = 10;\n" -" println!(\"x: {x}\");\n" -" // x = 20;\n" -" // println!(\"x: {x}\");\n" -"}\n" -"```" -msgstr "" - -#: src/basic-syntax/variables.md:17 +#: src/basic-syntax/variables.md:18 msgid "" "Due to type inference the `i32` is optional. We will gradually show the " "types less and less as the course progresses." @@ -4003,35 +3500,13 @@ msgstr "" msgid "Rust will look at how the variable is _used_ to determine the type:" msgstr "" -#: src/basic-syntax/type-inference.md:5 -msgid "" -"```rust,editable\n" -"fn takes_u32(x: u32) {\n" -" println!(\"u32: {x}\");\n" -"}\n" -"\n" -"fn takes_i8(y: i8) {\n" -" println!(\"i8: {y}\");\n" -"}\n" -"\n" -"fn main() {\n" -" let x = 10;\n" -" let y = 20;\n" -"\n" -" takes_u32(x);\n" -" takes_i8(y);\n" -" // takes_u32(y);\n" -"}\n" -"```" -msgstr "" - -#: src/basic-syntax/type-inference.md:26 +#: src/basic-syntax/type-inference.md:27 msgid "" "This slide demonstrates how the Rust compiler infers types based on " "constraints given by variable declarations and usages." msgstr "" -#: src/basic-syntax/type-inference.md:28 +#: src/basic-syntax/type-inference.md:29 msgid "" "It is very important to emphasize that variables declared like this are not " "of some sort of dynamic \"any type\" that can hold any data. The machine " @@ -4040,29 +3515,14 @@ msgid "" "code." msgstr "" -#: src/basic-syntax/type-inference.md:32 +#: src/basic-syntax/type-inference.md:33 msgid "" "The following code tells the compiler to copy into a certain generic " "container without the code ever explicitly specifying the contained type, " "using `_` as a placeholder:" msgstr "" -#: src/basic-syntax/type-inference.md:34 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let mut v = Vec::new();\n" -" v.push((10, false));\n" -" v.push((20, true));\n" -" println!(\"v: {v:?}\");\n" -"\n" -" let vv = v.iter().collect::>();\n" -" println!(\"vv: {vv:?}\");\n" -"}\n" -"```" -msgstr "" - -#: src/basic-syntax/type-inference.md:46 +#: src/basic-syntax/type-inference.md:48 msgid "" "[`collect`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator." "html#method.collect) relies on [`FromIterator`](https://doc.rust-lang.org/" @@ -4092,51 +3552,29 @@ msgid "" "inlined wherever they are used:" msgstr "" -#: src/basic-syntax/static-and-const.md:11 -msgid "" -"```rust,editable\n" -"const DIGEST_SIZE: usize = 3;\n" -"const ZERO: Option = Some(42);\n" -"\n" -"fn compute_digest(text: &str) -> [u8; DIGEST_SIZE] {\n" -" let mut digest = [ZERO.unwrap_or(0); DIGEST_SIZE];\n" -" for (idx, &b) in text.as_bytes().iter().enumerate() {\n" -" digest[idx % DIGEST_SIZE] = digest[idx % DIGEST_SIZE]." -"wrapping_add(b);\n" -" }\n" -" digest\n" -"}\n" -"\n" -"fn main() {\n" -" let digest = compute_digest(\"Hello\");\n" -" println!(\"Digest: {digest:?}\");\n" -"}\n" -"```" -msgstr "" - -#: src/basic-syntax/static-and-const.md:29 +#: src/basic-syntax/static-and-const.md:30 msgid "" "According to the [Rust RFC Book](https://rust-lang.github.io/rfcs/0246-const-" "vs-static.html) these are inlined upon use." msgstr "" -#: src/basic-syntax/static-and-const.md:31 +#: src/basic-syntax/static-and-const.md:32 msgid "" "Only functions marked `const` can be called at compile time to generate " "`const` values. `const` functions can however be called at runtime." msgstr "" -#: src/basic-syntax/static-and-const.md:33 +#: src/basic-syntax/static-and-const.md:34 msgid "`static`" msgstr "" -#: src/basic-syntax/static-and-const.md:35 +#: src/basic-syntax/static-and-const.md:36 msgid "" "Static variables will live during the whole execution of the program, and " "therefore will not move:" msgstr "" -#: src/basic-syntax/static-and-const.md:37 +#: src/basic-syntax/static-and-const.md:38 msgid "" "```rust,editable\n" "static BANNER: &str = \"Welcome to RustOS 3.14\";\n" @@ -4147,7 +3585,7 @@ msgid "" "```" msgstr "" -#: src/basic-syntax/static-and-const.md:45 +#: src/basic-syntax/static-and-const.md:46 msgid "" "As noted in the [Rust RFC Book](https://rust-lang.github.io/rfcs/0246-const-" "vs-static.html), these are not inlined upon use and have an actual " @@ -4157,7 +3595,7 @@ msgid "" "`const` is generally preferred." msgstr "" -#: src/basic-syntax/static-and-const.md:49 +#: src/basic-syntax/static-and-const.md:50 msgid "" "Because `static` variables are accessible from any thread, they must be " "`Sync`. Interior mutability is possible through a [`Mutex`](https://doc.rust-" @@ -4167,90 +3605,90 @@ msgid "" "unsafe/mutable-static-variables.md) in the chapter on Unsafe Rust." msgstr "" -#: src/basic-syntax/static-and-const.md:57 +#: src/basic-syntax/static-and-const.md:58 msgid "Mention that `const` behaves semantically similar to C++'s `constexpr`." msgstr "" -#: src/basic-syntax/static-and-const.md:58 +#: src/basic-syntax/static-and-const.md:59 msgid "" "`static`, on the other hand, is much more similar to a `const` or mutable " "global variable in C++." msgstr "" -#: src/basic-syntax/static-and-const.md:59 +#: src/basic-syntax/static-and-const.md:60 msgid "" "`static` provides object identity: an address in memory and state as " "required by types with interior mutability such as `Mutex`." msgstr "" -#: src/basic-syntax/static-and-const.md:60 +#: src/basic-syntax/static-and-const.md:61 msgid "" "It isn't super common that one would need a runtime evaluated constant, but " "it is helpful and safer than using a static." msgstr "" -#: src/basic-syntax/static-and-const.md:61 +#: src/basic-syntax/static-and-const.md:62 msgid "`thread_local` data can be created with the macro `std::thread_local`." msgstr "" -#: src/basic-syntax/static-and-const.md:63 +#: src/basic-syntax/static-and-const.md:64 msgid "Properties table:" msgstr "" -#: src/basic-syntax/static-and-const.md:65 +#: src/basic-syntax/static-and-const.md:66 msgid "Property" msgstr "" -#: src/basic-syntax/static-and-const.md:65 +#: src/basic-syntax/static-and-const.md:66 msgid "Static" msgstr "" -#: src/basic-syntax/static-and-const.md:65 +#: src/basic-syntax/static-and-const.md:66 msgid "Constant" msgstr "" -#: src/basic-syntax/static-and-const.md:67 +#: src/basic-syntax/static-and-const.md:68 msgid "Has an address in memory" msgstr "" -#: src/basic-syntax/static-and-const.md:67 #: src/basic-syntax/static-and-const.md:68 -#: src/basic-syntax/static-and-const.md:70 +#: src/basic-syntax/static-and-const.md:69 #: src/basic-syntax/static-and-const.md:71 +#: src/basic-syntax/static-and-const.md:72 msgid "Yes" msgstr "" -#: src/basic-syntax/static-and-const.md:67 +#: src/basic-syntax/static-and-const.md:68 msgid "No (inlined)" msgstr "" -#: src/basic-syntax/static-and-const.md:68 +#: src/basic-syntax/static-and-const.md:69 msgid "Lives for the entire duration of the program" msgstr "" -#: src/basic-syntax/static-and-const.md:68 #: src/basic-syntax/static-and-const.md:69 -#: src/basic-syntax/static-and-const.md:71 +#: src/basic-syntax/static-and-const.md:70 +#: src/basic-syntax/static-and-const.md:72 msgid "No" msgstr "" -#: src/basic-syntax/static-and-const.md:69 +#: src/basic-syntax/static-and-const.md:70 msgid "Can be mutable" msgstr "" -#: src/basic-syntax/static-and-const.md:69 +#: src/basic-syntax/static-and-const.md:70 msgid "Yes (unsafe)" msgstr "" -#: src/basic-syntax/static-and-const.md:70 +#: src/basic-syntax/static-and-const.md:71 msgid "Evaluated at compile time" msgstr "" -#: src/basic-syntax/static-and-const.md:70 +#: src/basic-syntax/static-and-const.md:71 msgid "Yes (initialised at compile time)" msgstr "" -#: src/basic-syntax/static-and-const.md:71 +#: src/basic-syntax/static-and-const.md:72 msgid "Inlined wherever it is used" msgstr "" @@ -4304,18 +3742,6 @@ msgid "" "does not change." msgstr "" -#: src/basic-syntax/scopes-shadowing.md:30 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let a = 1;\n" -" let b = &a;\n" -" let a = a + 1;\n" -" println!(\"{a} {b}\");\n" -"}\n" -"```" -msgstr "" - #: src/enums.md:3 msgid "" "The `enum` keyword allows the creation of a type which has a few different " @@ -4517,172 +3943,62 @@ msgid "" "You can control the discriminant if needed (e.g., for compatibility with C):" msgstr "" -#: src/enums/sizes.md:34 -msgid "" -"```rust,editable\n" -"#[repr(u32)]\n" -"enum Bar {\n" -" A, // 0\n" -" B = 10000,\n" -" C, // 10001\n" -"}\n" -"\n" -"fn main() {\n" -" println!(\"A: {}\", Bar::A as u32);\n" -" println!(\"B: {}\", Bar::B as u32);\n" -" println!(\"C: {}\", Bar::C as u32);\n" -"}\n" -"```" -msgstr "" - -#: src/enums/sizes.md:49 +#: src/enums/sizes.md:50 msgid "" "Without `repr`, the discriminant type takes 2 bytes, because 10001 fits 2 " "bytes." msgstr "" -#: src/enums/sizes.md:53 +#: src/enums/sizes.md:54 msgid "Try out other types such as" msgstr "" -#: src/enums/sizes.md:55 +#: src/enums/sizes.md:56 msgid "`dbg_size!(bool)`: size 1 bytes, align: 1 bytes," msgstr "" -#: src/enums/sizes.md:56 +#: src/enums/sizes.md:57 msgid "" "`dbg_size!(Option)`: size 1 bytes, align: 1 bytes (niche optimization, " "see below)," msgstr "" -#: src/enums/sizes.md:57 +#: src/enums/sizes.md:58 msgid "`dbg_size!(&i32)`: size 8 bytes, align: 8 bytes (on a 64-bit machine)," msgstr "" -#: src/enums/sizes.md:58 +#: src/enums/sizes.md:59 msgid "" "`dbg_size!(Option<&i32>)`: size 8 bytes, align: 8 bytes (null pointer " "optimization, see below)." msgstr "" -#: src/enums/sizes.md:60 +#: src/enums/sizes.md:61 msgid "" "Niche optimization: Rust will merge unused bit patterns for the enum " "discriminant." msgstr "" -#: src/enums/sizes.md:63 +#: src/enums/sizes.md:64 msgid "" "Null pointer optimization: For [some types](https://doc.rust-lang.org/std/" "option/#representation), Rust guarantees that `size_of::()` equals " "`size_of::>()`." msgstr "" -#: src/enums/sizes.md:67 +#: src/enums/sizes.md:68 msgid "" "Example code if you want to show how the bitwise representation _may_ look " "like in practice. It's important to note that the compiler provides no " "guarantees regarding this representation, therefore this is totally unsafe." msgstr "" -#: src/enums/sizes.md:70 -msgid "" -"```rust,editable\n" -"use std::mem::transmute;\n" -"\n" -"macro_rules! dbg_bits {\n" -" ($e:expr, $bit_type:ty) => {\n" -" println!(\"- {}: {:#x}\", stringify!($e), transmute::<_, " -"$bit_type>($e));\n" -" };\n" -"}\n" -"\n" -"fn main() {\n" -" // TOTALLY UNSAFE. Rust provides no guarantees about the bitwise\n" -" // representation of types.\n" -" unsafe {\n" -" println!(\"Bitwise representation of bool\");\n" -" dbg_bits!(false, u8);\n" -" dbg_bits!(true, u8);\n" -"\n" -" println!(\"Bitwise representation of Option\");\n" -" dbg_bits!(None::, u8);\n" -" dbg_bits!(Some(false), u8);\n" -" dbg_bits!(Some(true), u8);\n" -"\n" -" println!(\"Bitwise representation of Option>\");\n" -" dbg_bits!(Some(Some(false)), u8);\n" -" dbg_bits!(Some(Some(true)), u8);\n" -" dbg_bits!(Some(None::), u8);\n" -" dbg_bits!(None::>, u8);\n" -"\n" -" println!(\"Bitwise representation of Option<&i32>\");\n" -" dbg_bits!(None::<&i32>, usize);\n" -" dbg_bits!(Some(&0i32), usize);\n" -" }\n" -"}\n" -"```" -msgstr "" - #: src/enums/sizes.md:105 msgid "" "More complex example if you want to discuss what happens when we chain more " "than 256 `Option`s together." msgstr "" -#: src/enums/sizes.md:107 -msgid "" -"```rust,editable\n" -"#![recursion_limit = \"1000\"]\n" -"\n" -"use std::mem::transmute;\n" -"\n" -"macro_rules! dbg_bits {\n" -" ($e:expr, $bit_type:ty) => {\n" -" println!(\"- {}: {:#x}\", stringify!($e), transmute::<_, " -"$bit_type>($e));\n" -" };\n" -"}\n" -"\n" -"// Macro to wrap a value in 2^n Some() where n is the number of \"@\" " -"signs.\n" -"// Increasing the recursion limit is required to evaluate this macro.\n" -"macro_rules! many_options {\n" -" ($value:expr) => { Some($value) };\n" -" ($value:expr, @) => {\n" -" Some(Some($value))\n" -" };\n" -" ($value:expr, @ $($more:tt)+) => {\n" -" many_options!(many_options!($value, $($more)+), $($more)+)\n" -" };\n" -"}\n" -"\n" -"fn main() {\n" -" // TOTALLY UNSAFE. Rust provides no guarantees about the bitwise\n" -" // representation of types.\n" -" unsafe {\n" -" assert_eq!(many_options!(false), Some(false));\n" -" assert_eq!(many_options!(false, @), Some(Some(false)));\n" -" assert_eq!(many_options!(false, @@), " -"Some(Some(Some(Some(false)))));\n" -"\n" -" println!(\"Bitwise representation of a chain of 128 Option's.\");\n" -" dbg_bits!(many_options!(false, @@@@@@@), u8);\n" -" dbg_bits!(many_options!(true, @@@@@@@), u8);\n" -"\n" -" println!(\"Bitwise representation of a chain of 256 Option's.\");\n" -" dbg_bits!(many_options!(false, @@@@@@@@), u16);\n" -" dbg_bits!(many_options!(true, @@@@@@@@), u16);\n" -"\n" -" println!(\"Bitwise representation of a chain of 257 Option's.\");\n" -" dbg_bits!(many_options!(Some(false), @@@@@@@@), u16);\n" -" dbg_bits!(many_options!(Some(true), @@@@@@@@), u16);\n" -" dbg_bits!(many_options!(None::, @@@@@@@@), u16);\n" -" }\n" -"}\n" -"```" -msgstr "" - #: src/control-flow/novel.md:3 msgid "" "Rust has a few control flow constructs which differ from other languages. " @@ -4723,7 +4039,7 @@ msgid "" msgstr "" #: src/control-flow/if-let-expressions.md:18 -#: src/control-flow/while-let-expressions.md:21 +#: src/control-flow/while-let-expressions.md:22 #: src/control-flow/match-expressions.md:23 msgid "" "See [pattern matching](../pattern-matching.md) for more details on patterns " @@ -4753,24 +4069,6 @@ msgid "" "normal control flow (with `panic`/`return`/`break`/`continue`):" msgstr "" -#: src/control-flow/if-let-expressions.md:28 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" println!(\"{:?}\", second_word_to_upper(\"foo bar\"));\n" -"}\n" -" \n" -"fn second_word_to_upper(s: &str) -> Option {\n" -" let mut it = s.split(' ');\n" -" let (Some(_), Some(item)) = (it.next(), it.next()) else {\n" -" return None;\n" -" };\n" -" Some(item.to_uppercase())\n" -"}\n" -"\n" -"```" -msgstr "" - #: src/control-flow/while-let-expressions.md:1 msgid "`while let` loops" msgstr "" @@ -4782,21 +4080,7 @@ msgid "" "repeatedly tests a value against a pattern:" msgstr "" -#: src/control-flow/while-let-expressions.md:6 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let v = vec![10, 20, 30];\n" -" let mut iter = v.into_iter();\n" -"\n" -" while let Some(x) = iter.next() {\n" -" println!(\"x: {x}\");\n" -" }\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/while-let-expressions.md:17 +#: src/control-flow/while-let-expressions.md:18 msgid "" "Here the iterator returned by `v.into_iter()` will return a `Option` on " "every call to `next()`. It returns `Some(x)` until it is done, after which " @@ -4804,13 +4088,13 @@ msgid "" "items." msgstr "" -#: src/control-flow/while-let-expressions.md:26 +#: src/control-flow/while-let-expressions.md:27 msgid "" "Point out that the `while let` loop will keep going as long as the value " "matches the pattern." msgstr "" -#: src/control-flow/while-let-expressions.md:27 +#: src/control-flow/while-let-expressions.md:28 msgid "" "You could rewrite the `while let` loop as an infinite loop with an if " "statement that breaks when there is no value to unwrap for `iter.next()`. " @@ -5265,6 +4549,140 @@ msgid "" "```" msgstr "" +#: src/exercises/day-1/pattern-matching.md:1 +msgid "Exercise: Expression Evaluation" +msgstr "" + +#: src/exercises/day-1/pattern-matching.md:3 +msgid "Let's write a simple recursive evaluator for arithmetic expressions. " +msgstr "" + +#: src/exercises/day-1/pattern-matching.md:5 +msgid "" +"```rust\n" +"/// An operation to perform on two subexpressions.\n" +"#[derive(Debug)]\n" +"enum Operation {\n" +" Add,\n" +" Sub,\n" +" Mul,\n" +" Div,\n" +"}\n" +"\n" +"/// An expression, in tree form.\n" +"#[derive(Debug)]\n" +"enum Expression {\n" +" /// An operation on two subexpressions.\n" +" Op {\n" +" op: Operation,\n" +" left: Box,\n" +" right: Box,\n" +" },\n" +"\n" +" /// A literal value\n" +" Value(i64),\n" +"}\n" +"\n" +"/// The result of evaluating an expression.\n" +"#[derive(Debug, PartialEq, Eq)]\n" +"enum Res {\n" +" /// Evaluation was successful, with the given result.\n" +" Ok(i64),\n" +" /// Evaluation failed, with the given error message.\n" +" Err(String),\n" +"}\n" +"// Allow `Ok` and `Err` as shorthands for `Res::Ok` and `Res::Err`.\n" +"use Res::{Err, Ok};\n" +"\n" +"fn eval(e: Expression) -> Res {\n" +" todo!()\n" +"}\n" +"\n" +"#[test]\n" +"fn test_value() {\n" +" assert_eq!(eval(Expression::Value(19)), Ok(19));\n" +"}\n" +"\n" +"#[test]\n" +"fn test_sum() {\n" +" assert_eq!(\n" +" eval(Expression::Op {\n" +" op: Operation::Add,\n" +" left: Box::new(Expression::Value(10)),\n" +" right: Box::new(Expression::Value(20)),\n" +" }),\n" +" Ok(30)\n" +" );\n" +"}\n" +"\n" +"#[test]\n" +"fn test_recursion() {\n" +" let term1 = Expression::Op {\n" +" op: Operation::Mul,\n" +" left: Box::new(Expression::Value(10)),\n" +" right: Box::new(Expression::Value(9)),\n" +" };\n" +" let term2 = Expression::Op {\n" +" op: Operation::Mul,\n" +" left: Box::new(Expression::Op {\n" +" op: Operation::Sub,\n" +" left: Box::new(Expression::Value(3)),\n" +" right: Box::new(Expression::Value(4)),\n" +" }),\n" +" right: Box::new(Expression::Value(5)),\n" +" };\n" +" assert_eq!(\n" +" eval(Expression::Op {\n" +" op: Operation::Add,\n" +" left: Box::new(term1),\n" +" right: Box::new(term2),\n" +" }),\n" +" Ok(85)\n" +" );\n" +"}\n" +"\n" +"#[test]\n" +"fn test_error() {\n" +" assert_eq!(\n" +" eval(Expression::Op {\n" +" op: Operation::Div,\n" +" left: Box::new(Expression::Value(99)),\n" +" right: Box::new(Expression::Value(0)),\n" +" }),\n" +" Err(String::from(\"division by zero\"))\n" +" );\n" +"}\n" +"```" +msgstr "" + +#: src/exercises/day-1/pattern-matching.md:100 +msgid "" +"The `Box` type here is a smart pointer, and will be covered in detail later " +"in the course. An expression can be \"boxed\" with `Box::new` as seen in the " +"tests. To evaluate a boxed expression, use the deref operator to \"unbox\" " +"it: `eval(*boxed_expr)`." +msgstr "" + +#: src/exercises/day-1/pattern-matching.md:105 +msgid "" +"Some expressions cannot be evaluated and will return an error. The `Res` " +"type represents either a successful value or an error with a message. This " +"is very similar to the standard-library `Result` which we will see later." +msgstr "" + +#: src/exercises/day-1/pattern-matching.md:109 +msgid "" +"Copy and paste the code into the Rust playground, and begin implementing " +"`eval`. The final product should pass the tests. It may be helpful to use " +"`todo!()` and get the tests to pass one-by-one." +msgstr "" + +#: src/exercises/day-1/pattern-matching.md:113 +msgid "" +"If you finish early, try writing a test that results in an integer overflow. " +"How could you handle this with `Res::Err` instead of a panic?" +msgstr "" + #: src/welcome-day-2.md:1 msgid "Welcome to Day 2" msgstr "" @@ -5389,36 +4807,6 @@ msgid "" "```" msgstr "" -#: src/memory-management/stack.md:12 -msgid "" -"```bob\n" -" Stack Heap\n" -".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - - - -.\n" -": : : :\n" -": s1 : : :\n" -": +-----------+-------+ : : +----+----+----+----+----+ :\n" -": | ptr | o---+---+-----+-->| H | e | l | l | o | :\n" -": | len | 5 | : : +----+----+----+----+----+ :\n" -": | capacity | 5 | : : :\n" -": +-----------+-------+ : : :\n" -": : `- - - - - - - - - - - - - - - -'\n" -"`- - - - - - - - - - - - - -'\n" -"```" -msgstr "" -"```bob\n" -" Stak Heap\n" -".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - - - -.\n" -": : : :\n" -": s1 : : :\n" -": +-----------+-------+ : : +----+----+----+----+----+ :\n" -": | ptr | o---+---+-----+-->| H | a | l | l | o | :\n" -": | len | 5 | : : +----+----+----+----+----+ :\n" -": | capacity | 5 | : : :\n" -": +-----------+-------+ : : :\n" -": : `- - - - - - - - - - - - - - - -'\n" -"`- - - - - - - - - - - - - -'\n" -"```" - #: src/memory-management/stack.md:28 msgid "" "Mention that a `String` is backed by a `Vec`, so it has a capacity and " @@ -5548,14 +4936,6 @@ msgid "" "Special move constructors are used when passing ownership to a function:" msgstr "" -#: src/memory-management/scope-based.md:27 -msgid "" -"```c++\n" -"std::unique_ptr person = find_person(\"Carla\");\n" -"say_hello(std::move(person));\n" -"```" -msgstr "" - #: src/memory-management/garbage-collection.md:1 msgid "Automatic Memory Management" msgstr "" @@ -5642,31 +5022,16 @@ msgid "" "to use a variable outside its scope:" msgstr "" -#: src/ownership.md:6 -msgid "" -"```rust,editable,compile_fail\n" -"struct Point(i32, i32);\n" -"\n" -"fn main() {\n" -" {\n" -" let p = Point(3, 4);\n" -" println!(\"x: {}\", p.0);\n" -" }\n" -" println!(\"y: {}\", p.1);\n" -"}\n" -"```" -msgstr "" - -#: src/ownership.md:18 +#: src/ownership.md:19 msgid "" "At the end of the scope, the variable is _dropped_ and the data is freed." msgstr "" -#: src/ownership.md:19 +#: src/ownership.md:20 msgid "A destructor can run here to free up resources." msgstr "" -#: src/ownership.md:20 +#: src/ownership.md:21 msgid "We say that the variable _owns_ the value." msgstr "" @@ -5724,51 +5089,23 @@ msgstr "" msgid "In Rust, clones are explicit (by using `clone`)." msgstr "" -#: src/ownership/moved-strings-rust.md:3 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let s1: String = String::from(\"Rust\");\n" -" let s2: String = s1;\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/moved-strings-rust.md:10 +#: src/ownership/moved-strings-rust.md:11 msgid "The heap data from `s1` is reused for `s2`." msgstr "" -#: src/ownership/moved-strings-rust.md:11 +#: src/ownership/moved-strings-rust.md:12 msgid "When `s1` goes out of scope, nothing happens (it has been moved from)." msgstr "" -#: src/ownership/moved-strings-rust.md:13 +#: src/ownership/moved-strings-rust.md:14 msgid "Before move to `s2`:" msgstr "" -#: src/ownership/moved-strings-rust.md:15 -msgid "" -"```bob\n" -" Stack Heap\n" -".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - -.\n" -": : : :\n" -": s1 : : :\n" -": +-----------+-------+ : : +----+----+----+----+ :\n" -": | ptr | o---+---+-----+-->| R | u | s | t | :\n" -": | len | 4 | : : +----+----+----+----+ :\n" -": | capacity | 4 | : : :\n" -": +-----------+-------+ : : :\n" -": : `- - - - - - - - - - - - - -'\n" -": :\n" -"`- - - - - - - - - - - - - -'\n" -"```" -msgstr "" - -#: src/ownership/moved-strings-rust.md:30 +#: src/ownership/moved-strings-rust.md:31 msgid "After move to `s2`:" msgstr "" -#: src/ownership/moved-strings-rust.md:32 +#: src/ownership/moved-strings-rust.md:33 msgid "" "```bob\n" " Stack Heap\n" @@ -5841,71 +5178,10 @@ msgstr "" msgid "Before copy-assignment:" msgstr "" -#: src/ownership/double-free-modern-cpp.md:16 -msgid "" -"```bob\n" -" Stack Heap\n" -".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n" -": : : :\n" -": s1 : : :\n" -": +-----------+-------+ : : +----+----+----+ :\n" -": | ptr | o---+---+--+--+-->| C | p | p | :\n" -": | len | 3 | : : +----+----+----+ :\n" -": | capacity | 3 | : : :\n" -": +-----------+-------+ : : :\n" -": : `- - - - - - - - - - - -'\n" -"`- - - - - - - - - - - - - -'\n" -"```" -msgstr "" - #: src/ownership/double-free-modern-cpp.md:30 msgid "After copy-assignment:" msgstr "" -#: src/ownership/double-free-modern-cpp.md:32 -msgid "" -"```bob\n" -" Stack Heap\n" -".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n" -": : : :\n" -": s1 : : :\n" -": +-----------+-------+ : : +----+----+----+ :\n" -": | ptr | o---+---+--+--+-->| C | p | p | :\n" -": | len | 3 | : : +----+----+----+ :\n" -": | capacity | 3 | : : :\n" -": +-----------+-------+ : : :\n" -": : : :\n" -": s2 : : :\n" -": +-----------+-------+ : : +----+----+----+ :\n" -": | ptr | o---+---+-----+-->| C | p | p | :\n" -": | len | 3 | : : +----+----+----+ :\n" -": | capacity | 3 | : : :\n" -": +-----------+-------+ : : :\n" -": : `- - - - - - - - - - - -'\n" -"`- - - - - - - - - - - - - -'\n" -"```" -msgstr "" -"```bob\n" -" Stak Heap\n" -".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n" -": : : :\n" -": s1 : : :\n" -": +-----------+-------+ : : +----+----+----+ :\n" -": | ptr | o---+---+--+--+-->| C | p | p | :\n" -": | len | 3 | : : +----+----+----+ :\n" -": | capacity | 3 | : : :\n" -": +-----------+-------+ : : :\n" -": : : :\n" -": s2 : : :\n" -": +-----------+-------+ : : +----+----+----+ :\n" -": | ptr | o---+---+-----+-->| C | p | p | :\n" -": | len | 3 | : : +----+----+----+ :\n" -": | capacity | 3 | : : :\n" -": +-----------+-------+ : : :\n" -": : `- - - - - - - - - - - -'\n" -"`- - - - - - - - - - - - - -'\n" -"```" - #: src/ownership/double-free-modern-cpp.md:57 msgid "" "C++ has made a slightly different choice than Rust. Because `=` copies data, " @@ -5984,95 +5260,68 @@ msgid "" "While move semantics are the default, certain types are copied by default:" msgstr "" -#: src/ownership/copy-clone.md:5 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let x = 42;\n" -" let y = x;\n" -" println!(\"x: {x}\");\n" -" println!(\"y: {y}\");\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/copy-clone.md:14 +#: src/ownership/copy-clone.md:15 msgid "These types implement the `Copy` trait." msgstr "" -#: src/ownership/copy-clone.md:16 +#: src/ownership/copy-clone.md:17 msgid "You can opt-in your own types to use copy semantics:" msgstr "" -#: src/ownership/copy-clone.md:18 -msgid "" -"```rust,editable\n" -"#[derive(Copy, Clone, Debug)]\n" -"struct Point(i32, i32);\n" -"\n" -"fn main() {\n" -" let p1 = Point(3, 4);\n" -" let p2 = p1;\n" -" println!(\"p1: {p1:?}\");\n" -" println!(\"p2: {p2:?}\");\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/copy-clone.md:30 +#: src/ownership/copy-clone.md:32 msgid "After the assignment, both `p1` and `p2` own their own data." msgstr "" -#: src/ownership/copy-clone.md:31 +#: src/ownership/copy-clone.md:33 msgid "We can also use `p1.clone()` to explicitly copy the data." msgstr "" -#: src/ownership/copy-clone.md:35 +#: src/ownership/copy-clone.md:37 msgid "Copying and cloning are not the same thing:" msgstr "" -#: src/ownership/copy-clone.md:37 +#: src/ownership/copy-clone.md:39 msgid "" "Copying refers to bitwise copies of memory regions and does not work on " "arbitrary objects." msgstr "" -#: src/ownership/copy-clone.md:38 +#: src/ownership/copy-clone.md:40 msgid "" "Copying does not allow for custom logic (unlike copy constructors in C++)." msgstr "" -#: src/ownership/copy-clone.md:39 +#: src/ownership/copy-clone.md:41 msgid "" "Cloning is a more general operation and also allows for custom behavior by " "implementing the `Clone` trait." msgstr "" -#: src/ownership/copy-clone.md:40 +#: src/ownership/copy-clone.md:42 msgid "Copying does not work on types that implement the `Drop` trait." msgstr "" -#: src/ownership/copy-clone.md:42 src/ownership/lifetimes-function-calls.md:29 +#: src/ownership/copy-clone.md:44 src/ownership/lifetimes-function-calls.md:30 msgid "In the above example, try the following:" msgstr "" -#: src/ownership/copy-clone.md:44 +#: src/ownership/copy-clone.md:46 msgid "" "Add a `String` field to `struct Point`. It will not compile because `String` " "is not a `Copy` type." msgstr "" -#: src/ownership/copy-clone.md:45 +#: src/ownership/copy-clone.md:47 msgid "" "Remove `Copy` from the `derive` attribute. The compiler error is now in the " "`println!` for `p1`." msgstr "" -#: src/ownership/copy-clone.md:46 +#: src/ownership/copy-clone.md:48 msgid "Show that it works if you clone `p1` instead." msgstr "" -#: src/ownership/copy-clone.md:48 +#: src/ownership/copy-clone.md:50 msgid "" "If students ask about `derive`, it is sufficient to say that this is a way " "to generate code in Rust at compile time. In this case the default " @@ -6085,38 +5334,19 @@ msgid "" "function _borrow_ the value:" msgstr "" -#: src/ownership/borrowing.md:6 -msgid "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Point(i32, i32);\n" -"\n" -"fn add(p1: &Point, p2: &Point) -> Point {\n" -" Point(p1.0 + p2.0, p1.1 + p2.1)\n" -"}\n" -"\n" -"fn main() {\n" -" let p1 = Point(3, 4);\n" -" let p2 = Point(10, 20);\n" -" let p3 = add(&p1, &p2);\n" -" println!(\"{p1:?} + {p2:?} = {p3:?}\");\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/borrowing.md:22 +#: src/ownership/borrowing.md:23 msgid "The `add` function _borrows_ two points and returns a new point." msgstr "" -#: src/ownership/borrowing.md:23 +#: src/ownership/borrowing.md:24 msgid "The caller retains ownership of the inputs." msgstr "" -#: src/ownership/borrowing.md:27 +#: src/ownership/borrowing.md:28 msgid "Notes on stack returns:" msgstr "" -#: src/ownership/borrowing.md:28 +#: src/ownership/borrowing.md:29 msgid "" "Demonstrate that the return from `add` is cheap because the compiler can " "eliminate the copy operation. Change the above code to print stack addresses " @@ -6126,33 +5356,11 @@ msgid "" "when changing to the \"RELEASE\" setting:" msgstr "" -#: src/ownership/borrowing.md:30 -msgid "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Point(i32, i32);\n" -"\n" -"fn add(p1: &Point, p2: &Point) -> Point {\n" -" let p = Point(p1.0 + p2.0, p1.1 + p2.1);\n" -" println!(\"&p.0: {:p}\", &p.0);\n" -" p\n" -"}\n" -"\n" -"pub fn main() {\n" -" let p1 = Point(3, 4);\n" -" let p2 = Point(10, 20);\n" -" let p3 = add(&p1, &p2);\n" -" println!(\"&p3.0: {:p}\", &p3.0);\n" -" println!(\"{p1:?} + {p2:?} = {p3:?}\");\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/borrowing.md:48 +#: src/ownership/borrowing.md:50 msgid "The Rust compiler can do return value optimization (RVO)." msgstr "" -#: src/ownership/borrowing.md:49 +#: src/ownership/borrowing.md:51 msgid "" "In C++, copy elision has to be defined in the language specification because " "constructors can have side effects. In Rust, this is not an issue at all. If " @@ -6172,37 +5380,19 @@ msgstr "" msgid "You can have exactly one `&mut T` value." msgstr "" -#: src/ownership/shared-unique-borrows.md:8 -msgid "" -"```rust,editable,compile_fail\n" -"fn main() {\n" -" let mut a: i32 = 10;\n" -" let b: &i32 = &a;\n" -"\n" -" {\n" -" let c: &mut i32 = &mut a;\n" -" *c = 20;\n" -" }\n" -"\n" -" println!(\"a: {a}\");\n" -" println!(\"b: {b}\");\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/shared-unique-borrows.md:25 +#: src/ownership/shared-unique-borrows.md:26 msgid "" "The above code does not compile because `a` is borrowed as mutable (through " "`c`) and as immutable (through `b`) at the same time." msgstr "" -#: src/ownership/shared-unique-borrows.md:26 +#: src/ownership/shared-unique-borrows.md:27 msgid "" "Move the `println!` statement for `b` before the scope that introduces `c` " "to make the code compile." msgstr "" -#: src/ownership/shared-unique-borrows.md:27 +#: src/ownership/shared-unique-borrows.md:28 msgid "" "After that change, the compiler realizes that `b` is only ever used before " "the new mutable borrow of `a` through `c`. This is a feature of the borrow " @@ -6221,7 +5411,7 @@ msgstr "" msgid "Lifetimes can also be explicit: `&'a Point`, `&'document str`." msgstr "" -#: src/ownership/lifetimes.md:7 src/ownership/lifetimes-function-calls.md:23 +#: src/ownership/lifetimes.md:7 src/ownership/lifetimes-function-calls.md:24 msgid "" "Read `&'a Point` as \"a borrowed `Point` which is valid for at least the " "lifetime `a`\"." @@ -6252,93 +5442,52 @@ msgid "" "value:" msgstr "" -#: src/ownership/lifetimes-function-calls.md:5 -msgid "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Point(i32, i32);\n" -"\n" -"fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n" -" if p1.0 < p2.0 { p1 } else { p2 }\n" -"}\n" -"\n" -"fn main() {\n" -" let p1: Point = Point(10, 10);\n" -" let p2: Point = Point(20, 20);\n" -" let p3: &Point = left_most(&p1, &p2);\n" -" println!(\"left-most point: {:?}\", p3);\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/lifetimes-function-calls.md:21 +#: src/ownership/lifetimes-function-calls.md:22 msgid "`'a` is a generic parameter, it is inferred by the compiler." msgstr "" -#: src/ownership/lifetimes-function-calls.md:22 +#: src/ownership/lifetimes-function-calls.md:23 msgid "Lifetimes start with `'` and `'a` is a typical default name." msgstr "" -#: src/ownership/lifetimes-function-calls.md:25 +#: src/ownership/lifetimes-function-calls.md:26 msgid "" "The _at least_ part is important when parameters are in different scopes." msgstr "" -#: src/ownership/lifetimes-function-calls.md:31 +#: src/ownership/lifetimes-function-calls.md:32 msgid "" "Move the declaration of `p2` and `p3` into a new scope (`{ ... }`), " "resulting in the following code:" msgstr "" -#: src/ownership/lifetimes-function-calls.md:32 -msgid "" -"```rust,ignore\n" -"#[derive(Debug)]\n" -"struct Point(i32, i32);\n" -"\n" -"fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n" -" if p1.0 < p2.0 { p1 } else { p2 }\n" -"}\n" -"\n" -"fn main() {\n" -" let p1: Point = Point(10, 10);\n" -" let p3: &Point;\n" -" {\n" -" let p2: Point = Point(20, 20);\n" -" p3 = left_most(&p1, &p2);\n" -" }\n" -" println!(\"left-most point: {:?}\", p3);\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/lifetimes-function-calls.md:50 +#: src/ownership/lifetimes-function-calls.md:52 msgid "Note how this does not compile since `p3` outlives `p2`." msgstr "" -#: src/ownership/lifetimes-function-calls.md:52 +#: src/ownership/lifetimes-function-calls.md:54 msgid "" "Reset the workspace and change the function signature to `fn left_most<'a, " "'b>(p1: &'a Point, p2: &'a Point) -> &'b Point`. This will not compile " "because the relationship between the lifetimes `'a` and `'b` is unclear." msgstr "" -#: src/ownership/lifetimes-function-calls.md:53 +#: src/ownership/lifetimes-function-calls.md:55 msgid "Another way to explain it:" msgstr "" -#: src/ownership/lifetimes-function-calls.md:54 +#: src/ownership/lifetimes-function-calls.md:56 msgid "" "Two references to two values are borrowed by a function and the function " "returns another reference." msgstr "" -#: src/ownership/lifetimes-function-calls.md:56 +#: src/ownership/lifetimes-function-calls.md:58 msgid "" "It must have come from one of those two inputs (or from a global variable)." msgstr "" -#: src/ownership/lifetimes-function-calls.md:57 +#: src/ownership/lifetimes-function-calls.md:59 msgid "" "Which one is it? The compiler needs to know, so at the call site the " "returned reference is not used for longer than a variable from where the " @@ -6593,22 +5742,6 @@ msgid "" "interchangeable with the struct type name" msgstr "" -#: src/structs/field-shorthand.md:29 -msgid "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Person {\n" -" name: String,\n" -" age: u8,\n" -"}\n" -"impl Person {\n" -" fn new(name: String, age: u8) -> Self {\n" -" Self { name, age }\n" -" }\n" -"}\n" -"```" -msgstr "" - #: src/structs/field-shorthand.md:41 msgid "" "Implement the `Default` trait for the struct. Define some fields and use the " @@ -6929,8 +6062,9 @@ msgid "" " }\n" "}\n" "\n" -"// Implement the methods below. Update the `self` parameter to\n" -"// indicate the method's required level of ownership over the object:\n" +"// Implement the methods below. Notice how the `self` parameter\n" +"// changes type to indicate the method's required level of ownership\n" +"// over the object:\n" "//\n" "// - `&self` for shared read-only access,\n" "// - `&mut self` for unique and mutable access,\n" @@ -6940,63 +6074,58 @@ msgid "" " todo!(\"Initialize and return a `Library` value\")\n" " }\n" "\n" -" //fn len(self) -> usize {\n" -" // todo!(\"Return the length of `self.books`\")\n" -" //}\n" +" fn len(&self) -> usize {\n" +" todo!(\"Return the length of `self.books`\")\n" +" }\n" "\n" -" //fn is_empty(self) -> bool {\n" -" // todo!(\"Return `true` if `self.books` is empty\")\n" -" //}\n" +" fn is_empty(&self) -> bool {\n" +" todo!(\"Return `true` if `self.books` is empty\")\n" +" }\n" "\n" -" //fn add_book(self, book: Book) {\n" -" // todo!(\"Add a new book to `self.books`\")\n" -" //}\n" +" fn add_book(&mut self, book: Book) {\n" +" todo!(\"Add a new book to `self.books`\")\n" +" }\n" "\n" -" //fn print_books(self) {\n" -" // todo!(\"Iterate over `self.books` and print each book's title and " +" fn print_books(&self) {\n" +" todo!(\"Iterate over `self.books` and print each book's title and " "year\")\n" -" //}\n" +" }\n" "\n" -" //fn oldest_book(self) -> Option<&Book> {\n" -" // todo!(\"Return a reference to the oldest book (if any)\")\n" -" //}\n" +" fn oldest_book(&self) -> Option<&Book> {\n" +" todo!(\"Return a reference to the oldest book (if any)\")\n" +" }\n" "}\n" "\n" -"// This shows the desired behavior. Uncomment the code below and\n" -"// implement the missing methods. You will need to update the\n" -"// method signatures, including the \"self\" parameter! You may\n" -"// also need to update the variable bindings within main.\n" "fn main() {\n" -" let library = Library::new();\n" +" let mut library = Library::new();\n" "\n" -" //println!(\"The library is empty: library.is_empty() -> {}\", library." -"is_empty());\n" -" //\n" -" //library.add_book(Book::new(\"Lord of the Rings\", 1954));\n" -" //library.add_book(Book::new(\"Alice's Adventures in Wonderland\", " +" println!(\n" +" \"The library is empty: library.is_empty() -> {}\",\n" +" library.is_empty()\n" +" );\n" +"\n" +" library.add_book(Book::new(\"Lord of the Rings\", 1954));\n" +" library.add_book(Book::new(\"Alice's Adventures in Wonderland\", " "1865));\n" -" //\n" -" //println!(\"The library is no longer empty: library.is_empty() -> {}\", " -"library.is_empty());\n" -" //\n" -" //\n" -" //library.print_books();\n" -" //\n" -" //match library.oldest_book() {\n" -" // Some(book) => println!(\"The oldest book is {}\", book.title),\n" -" // None => println!(\"The library is empty!\"),\n" -" //}\n" -" //\n" -" //println!(\"The library has {} books\", library.len());\n" -" //library.print_books();\n" +"\n" +" println!(\n" +" \"The library is no longer empty: library.is_empty() -> {}\",\n" +" library.is_empty()\n" +" );\n" +"\n" +" library.print_books();\n" +"\n" +" match library.oldest_book() {\n" +" Some(book) => println!(\"The oldest book is {}\", book.title),\n" +" None => println!(\"The library is empty!\"),\n" +" }\n" +"\n" +" println!(\"The library has {} books\", library.len());\n" +" library.print_books();\n" "}\n" "```" msgstr "" -#: src/exercises/day-2/book-library.md:102 -msgid "[Solution](solutions-afternoon.md#designing-a-library)" -msgstr "" - #: src/exercises/day-2/health-statistics.md:3 msgid "" "You're working on implementing a health-monitoring system. As part of that, " @@ -7044,36 +6173,38 @@ msgid "" "\n" "impl User {\n" " pub fn new(name: String, age: u32, height: f32) -> Self {\n" -" unimplemented!()\n" +" todo!(\"Create a new User instance\")\n" " }\n" "\n" " pub fn name(&self) -> &str {\n" -" unimplemented!()\n" +" todo!(\"Return the user's name\")\n" " }\n" "\n" " pub fn age(&self) -> u32 {\n" -" unimplemented!()\n" +" todo!(\"Return the user's age\")\n" " }\n" "\n" " pub fn height(&self) -> f32 {\n" -" unimplemented!()\n" +" todo!(\"Return the user's height\")\n" " }\n" "\n" " pub fn doctor_visits(&self) -> u32 {\n" -" unimplemented!()\n" +" todo!(\"Return the number of time the user has visited the " +"doctor\")\n" " }\n" "\n" " pub fn set_age(&mut self, new_age: u32) {\n" -" unimplemented!()\n" +" todo!(\"Set the user's age\")\n" " }\n" "\n" " pub fn set_height(&mut self, new_height: f32) {\n" -" unimplemented!()\n" +" todo!(\"Set the user's height\")\n" " }\n" "\n" " pub fn visit_doctor(&mut self, measurements: Measurements) -> " "HealthReport {\n" -" unimplemented!()\n" +" todo!(\"Update a user's statistics based on measurements from a " +"visit to the doctor\")\n" " }\n" "}\n" "\n" @@ -7199,11 +6330,21 @@ msgid "" " let first: Option<&i8> = numbers.first();\n" " println!(\"first: {first:?}\");\n" "\n" -" let idx: Result = numbers.binary_search(&10);\n" -" println!(\"idx: {idx:?}\");\n" +" let arr: Result<[i8; 3], Vec> = numbers.try_into();\n" +" println!(\"arr: {arr:?}\");\n" "}\n" "```" msgstr "" +"```rust,editable\n" +"fn main() {\n" +" let numbers = vec![10, 20, 30];\n" +" let first: Option<&i8> = numbers.first();\n" +" println!(\"first: {first:?}\");\n" +"\n" +" let arr: Result<[i8; 3], Vec> = numbers.try_into();\n" +" println!(\"arr: {arr:?}\");\n" +"}\n" +"```" #: src/std/option-result.md:18 msgid "`Option` and `Result` are widely used not just in the standard library." @@ -7220,17 +6361,18 @@ msgid "" msgstr "" #: src/std/option-result.md:21 -msgid "`binary_search` returns `Result`." +msgid "" +"`try_into` attempts to convert the vector into a fixed-sized array. This can " +"fail:" msgstr "" #: src/std/option-result.md:22 -msgid "If found, `Result::Ok` holds the index where the element is found." +msgid "" +"If the vector has the right size, `Result::Ok` is returned with the array." msgstr "" #: src/std/option-result.md:23 -msgid "" -"Otherwise, `Result::Err` contains the index where such an element should be " -"inserted." +msgid "Otherwise, `Result::Err` is returned with the original vector." msgstr "" #: src/std/string.md:3 @@ -7547,22 +6689,6 @@ msgid "" "```" msgstr "" -#: src/std/box.md:13 -msgid "" -"```bob\n" -" Stack Heap\n" -".- - - - - - -. .- - - - - - -.\n" -": : : :\n" -": five : : :\n" -": +-----+ : : +-----+ :\n" -": | o---|---+-----+-->| 5 | :\n" -": +-----+ : : +-----+ :\n" -": : : :\n" -": : : :\n" -"`- - - - - - -' `- - - - - - -'\n" -"```" -msgstr "" - #: src/std/box.md:26 msgid "" "`Box` implements `Deref`, which means that you can [call " @@ -8045,26 +7171,11 @@ msgid "" "will typically see something like this at the top of each module:" msgstr "" -#: src/modules/paths.md:16 -msgid "" -"```rust,editable\n" -"use std::collections::HashSet;\n" -"use std::mem::transmute;\n" -"```" -msgstr "" - #: src/modules/filesystem.md:3 msgid "" "Omitting the module content will tell Rust to look for it in another file:" msgstr "" -#: src/modules/filesystem.md:5 -msgid "" -"```rust,editable,compile_fail\n" -"mod garden;\n" -"```" -msgstr "" - #: src/modules/filesystem.md:9 msgid "" "This tells rust that the `garden` module content is found at `src/garden." @@ -8126,17 +7237,6 @@ msgstr "" msgid "Deeper nesting can use folders, even if the main module is a file:" msgstr "" -#: src/modules/filesystem.md:44 -msgid "" -"```ignore\n" -"src/\n" -"├── main.rs\n" -"├── top_module.rs\n" -"└── top_module/\n" -" └── sub_module.rs\n" -"```" -msgstr "" - #: src/modules/filesystem.md:52 msgid "" "The place rust will look for modules can be changed with a compiler " @@ -8184,16 +7284,6 @@ msgid "" "back:" msgstr "" -#: src/exercises/day-2/iterators-and-ownership.md:13 -msgid "" -"```rust\n" -"pub trait Iterator {\n" -" type Item;\n" -" fn next(&mut self) -> Option;\n" -"}\n" -"```" -msgstr "" - #: src/exercises/day-2/iterators-and-ownership.md:20 msgid "You use this trait like this:" msgstr "" @@ -8245,18 +7335,6 @@ msgid "" "iterator:" msgstr "" -#: src/exercises/day-2/iterators-and-ownership.md:53 -msgid "" -"```rust\n" -"pub trait IntoIterator {\n" -" type Item;\n" -" type IntoIter: Iterator;\n" -"\n" -" fn into_iter(self) -> Self::IntoIter;\n" -"}\n" -"```" -msgstr "" - #: src/exercises/day-2/iterators-and-ownership.md:62 msgid "" "The syntax here means that every implementation of `IntoIterator` must " @@ -8524,40 +7602,10 @@ msgstr "" msgid "Generic code is turned into non-generic code based on the call sites:" msgstr "" -#: src/generics/monomorphization.md:5 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let integer = Some(5);\n" -" let float = Some(5.0);\n" -"}\n" -"```" -msgstr "" - #: src/generics/monomorphization.md:12 msgid "behaves as if you wrote" msgstr "" -#: src/generics/monomorphization.md:14 -msgid "" -"```rust,editable\n" -"enum Option_i32 {\n" -" Some(i32),\n" -" None,\n" -"}\n" -"\n" -"enum Option_f64 {\n" -" Some(f64),\n" -" None,\n" -"}\n" -"\n" -"fn main() {\n" -" let integer = Option_i32::Some(5);\n" -" let float = Option_f64::Some(5.0);\n" -"}\n" -"```" -msgstr "" - #: src/generics/monomorphization.md:31 msgid "" "This is a zero-cost abstraction: you get exactly the same result as if you " @@ -8869,36 +7917,10 @@ msgstr "" msgid "Make `Equals` a super trait for `NotEquals`." msgstr "" -#: src/traits/default-methods.md:38 -msgid "" -"```rust,editable,compile_fail\n" -"trait NotEquals: Equals {\n" -" fn not_equals(&self, other: &Self) -> bool {\n" -" !self.equals(other)\n" -" }\n" -"}\n" -"```" -msgstr "" - #: src/traits/default-methods.md:46 msgid "Provide a blanket implementation of `NotEquals` for `Equals`." msgstr "" -#: src/traits/default-methods.md:47 -msgid "" -"```rust,editable,compile_fail\n" -"trait NotEquals {\n" -" fn not_equals(&self, other: &Self) -> bool;\n" -"}\n" -"\n" -"impl NotEquals for T where T: Equals {\n" -" fn not_equals(&self, other: &Self) -> bool {\n" -" !self.equals(other)\n" -" }\n" -"}\n" -"```" -msgstr "" - #: src/traits/default-methods.md:58 msgid "" "With the blanket implementation, you no longer need `Equals` as a super " @@ -8947,18 +7969,6 @@ msgstr "" msgid "Show a `where` clause, students will encounter it when reading code." msgstr "" -#: src/traits/trait-bounds.md:37 -msgid "" -"```rust,ignore\n" -"fn duplicate(a: T) -> (T, T)\n" -"where\n" -" T: Clone,\n" -"{\n" -" (a.clone(), a.clone())\n" -"}\n" -"```" -msgstr "" - #: src/traits/trait-bounds.md:46 msgid "It declutters the function signature if you have many parameters." msgstr "" @@ -9149,19 +8159,6 @@ msgid "" "std/iter/trait.Iterator.html)." msgstr "" -#: src/traits/from-iterator.md:5 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let primes = vec![2, 3, 5, 7];\n" -" let prime_squares = primes\n" -" .into_iter()\n" -" .map(|prime| prime * prime)\n" -" .collect::>();\n" -"}\n" -"```" -msgstr "" - #: src/traits/from-iterator.md:17 msgid "" "`Iterator` implements `fn collect(self) -> B where B: FromIterator value,\n" -" Err(err) => return Err(err),\n" -"}\n" -"```" -msgstr "" - #: src/error-handling/try-operator.md:13 msgid "into the much simpler" msgstr "" -#: src/error-handling/try-operator.md:15 -msgid "" -"```rust,ignore\n" -"some_expression?\n" -"```" -msgstr "" - #: src/error-handling/try-operator.md:19 msgid "We can use this to simplify our error handling code:" msgstr "" @@ -10175,27 +9161,10 @@ msgid "" "indicated:" msgstr "" -#: src/error-handling/converting-error-types.md:5 -msgid "" -"```rust,ignore\n" -"expression?\n" -"```" -msgstr "" - #: src/error-handling/converting-error-types.md:9 msgid "works the same as" msgstr "" -#: src/error-handling/converting-error-types.md:11 -msgid "" -"```rust,ignore\n" -"match expression {\n" -" Ok(value) => value,\n" -" Err(err) => return Err(From::from(err)),\n" -"}\n" -"```" -msgstr "" - #: src/error-handling/converting-error-types.md:18 msgid "" "The `From::from` call here means we attempt to convert the error type to the " @@ -10549,18 +9518,6 @@ msgstr "" msgid "Create a `.rs` file under `tests/`:" msgstr "" -#: src/testing/integration-tests.md:7 -msgid "" -"```rust,ignore\n" -"use my_library::init;\n" -"\n" -"#[test]\n" -"fn test_init() {\n" -" assert!(init().is_ok());\n" -"}\n" -"```" -msgstr "" - #: src/testing/integration-tests.md:16 msgid "These tests only have access to the public API of your crate." msgstr "" @@ -11268,15 +10225,6 @@ msgid "" "have access to one or create a new one with:" msgstr "" -#: src/android/setup.md:6 -msgid "" -"```shell\n" -"source build/envsetup.sh\n" -"lunch aosp_cf_x86_64_phone-userdebug\n" -"acloud create\n" -"```" -msgstr "" - #: src/android/setup.md:12 msgid "" "Please see the [Android Developer Codelab](https://source.android.com/docs/" @@ -11425,13 +10373,6 @@ msgid "" "```" msgstr "" -#: src/android/build-rules/binary.md:35 -msgid "" -"```text\n" -"Hello from Rust!\n" -"```" -msgstr "" - #: src/android/build-rules/library.md:1 msgid "Rust Libraries" msgstr "" @@ -11522,14 +10463,6 @@ msgid "" "```" msgstr "" -#: src/android/build-rules/library.md:67 -msgid "" -"```text\n" -"Hello Bob, it is very\n" -"nice to meet you!\n" -"```" -msgstr "" - #: src/android/aidl.md:3 msgid "" "The [Android Interface Definition Language (AIDL)](https://developer.android." @@ -11557,19 +10490,6 @@ msgid "" "_birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl_:" msgstr "" -#: src/android/aidl/interface.md:7 -msgid "" -"```java\n" -"package com.example.birthdayservice;\n" -"\n" -"/** Birthday service interface. */\n" -"interface IBirthdayService {\n" -" /** Generate a Happy Birthday message. */\n" -" String wishHappyBirthday(String name, int years);\n" -"}\n" -"```" -msgstr "" - #: src/android/aidl/interface.md:17 msgid "_birthday_service/aidl/Android.bp_:" msgstr "" @@ -11726,46 +10646,10 @@ msgstr "" msgid "In another terminal, check that the service runs:" msgstr "" -#: src/android/aidl/deploy.md:13 -msgid "" -"```shell\n" -"adb shell service check birthdayservice\n" -"```" -msgstr "" - -#: src/android/aidl/deploy.md:17 -msgid "" -"```text\n" -"Service birthdayservice: found\n" -"```" -msgstr "" - #: src/android/aidl/deploy.md:21 msgid "You can also call the service with `service call`:" msgstr "" -#: src/android/aidl/deploy.md:23 -msgid "" -"```shell\n" -"adb shell service call birthdayservice 1 s16 Bob i32 24\n" -"```" -msgstr "" - -#: src/android/aidl/deploy.md:27 -msgid "" -"```text\n" -"Result: Parcel(\n" -" 0x00000000: 00000000 00000036 00610048 00700070 '....6...H.a.p.p.'\n" -" 0x00000010: 00200079 00690042 00740072 00640068 'y. .B.i.r.t.h.d.'\n" -" 0x00000020: 00790061 00420020 0062006f 0020002c 'a.y. .B.o.b.,. .'\n" -" 0x00000030: 006f0063 0067006e 00610072 00750074 'c.o.n.g.r.a.t.u.'\n" -" 0x00000040: 0061006c 00690074 006e006f 00200073 'l.a.t.i.o.n.s. .'\n" -" 0x00000050: 00690077 00680074 00740020 00650068 'w.i.t.h. .t.h.e.'\n" -" 0x00000060: 00320020 00200034 00650079 00720061 ' .2.4. .y.e.a.r.'\n" -" 0x00000070: 00210073 00000000 's.!..... ')\n" -"```" -msgstr "" - #: src/android/aidl/client.md:1 msgid "AIDL Client" msgstr "" @@ -11848,32 +10732,12 @@ msgid "" "```" msgstr "" -#: src/android/aidl/client.md:62 -msgid "" -"```text\n" -"Happy Birthday Charlie, congratulations with the 60 years!\n" -"```" -msgstr "" - #: src/android/aidl/changing.md:3 msgid "" "Let us extend the API with more functionality: we want to let clients " "specify a list of lines for the birthday card:" msgstr "" -#: src/android/aidl/changing.md:6 -msgid "" -"```java\n" -"package com.example.birthdayservice;\n" -"\n" -"/** Birthday service interface. */\n" -"interface IBirthdayService {\n" -" /** Generate a Happy Birthday message. */\n" -" String wishHappyBirthday(String name, int years, in String[] text);\n" -"}\n" -"```" -msgstr "" - #: src/android/logging.md:3 msgid "" "You should use the `log` crate to automatically log to `logcat` (on-device) " @@ -11945,27 +10809,6 @@ msgstr "" msgid "The logs show up in `adb logcat`:" msgstr "" -#: src/android/logging.md:52 -msgid "" -"```shell\n" -"adb logcat -s rust\n" -"```" -msgstr "" -"```shell\n" -"adb logcat -s rust\n" -"```" - -#: src/android/logging.md:56 -msgid "" -"```text\n" -"09-08 08:38:32.454 2420 2420 D rust: hello_rust_logs: Starting program.\n" -"09-08 08:38:32.454 2420 2420 I rust: hello_rust_logs: Things are going " -"fine.\n" -"09-08 08:38:32.454 2420 2420 E rust: hello_rust_logs: Something went " -"wrong!\n" -"```" -msgstr "" - #: src/android/interoperability.md:3 msgid "" "Rust has excellent support for interoperability with other languages. This " @@ -12060,18 +10903,6 @@ msgstr "" msgid "_interoperability/bindgen/libbirthday.h_:" msgstr "" -#: src/android/interoperability/with-c/bindgen.md:10 -msgid "" -"```c\n" -"typedef struct card {\n" -" const char* name;\n" -" int years;\n" -"} card;\n" -"\n" -"void print_card(const card* card);\n" -"```" -msgstr "" - #: src/android/interoperability/with-c/bindgen.md:19 msgid "_interoperability/bindgen/libbirthday.c_:" msgstr "" @@ -12230,13 +11061,6 @@ msgid "" "```" msgstr "" -#: src/android/interoperability/with-c/bindgen.md:122 -msgid "" -"```shell\n" -"atest libbirthday_bindgen_test\n" -"```" -msgstr "" - #: src/android/interoperability/with-c/rust.md:1 msgid "Calling Rust" msgstr "" @@ -12526,15 +11350,6 @@ msgstr "" msgid "Finally, you can build, sync, and run the binary:" msgstr "" -#: src/android/interoperability/java.md:75 -msgid "" -"```shell\n" -"m helloworld_jni\n" -"adb sync # requires adb root && adb remount\n" -"adb shell /system/bin/helloworld_jni\n" -"```" -msgstr "" - #: src/exercises/android/morning.md:3 msgid "" "This is a group exercise: We will look at one of the projects you work with " @@ -12603,26 +11418,6 @@ msgid "" "To get started, install some tools we'll need later. On gLinux or Debian:" msgstr "" -#: src/bare-metal.md:22 -msgid "" -"```bash\n" -"sudo apt install gcc-aarch64-linux-gnu gdb-multiarch libudev-dev picocom pkg-" -"config qemu-system-arm\n" -"rustup update\n" -"rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n" -"rustup component add llvm-tools-preview\n" -"cargo install cargo-binutils cargo-embed\n" -"```" -msgstr "" -"```bash\n" -"sudo apt install gcc-aarch64-linux-gnu gdb-multiarch libudev-dev picocom pkg-" -"config qemu-system-arm\n" -"rustup update\n" -"rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n" -"rustup component add llvm-tools-preview\n" -"cargo install cargo-binutils cargo-embed\n" -"```" - #: src/bare-metal.md:30 msgid "" "And give users in the `plugdev` group access to the micro:bit programmer:" @@ -12648,28 +11443,6 @@ msgstr "" msgid "On MacOS:" msgstr "På MacOS:" -#: src/bare-metal.md:40 -msgid "" -"```bash\n" -"xcode-select --install\n" -"brew install gdb picocom qemu\n" -"brew install --cask gcc-aarch64-embedded\n" -"rustup update\n" -"rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n" -"rustup component add llvm-tools-preview\n" -"cargo install cargo-binutils cargo-embed\n" -"```" -msgstr "" -"```bash\n" -"xcode-select --install\n" -"brew install gdb picocom qemu\n" -"brew install --cask gcc-aarch64-embedded\n" -"rustup update\n" -"rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n" -"rustup component add llvm-tools-preview\n" -"cargo install cargo-binutils cargo-embed\n" -"```" - #: src/bare-metal/no_std.md:1 msgid "`no_std`" msgstr "`no_std`" @@ -12782,32 +11555,6 @@ msgstr "" msgid "A minimal `no_std` program" msgstr "" -#: src/bare-metal/minimal.md:3 -msgid "" -"```rust,editable,compile_fail\n" -"#![no_main]\n" -"#![no_std]\n" -"\n" -"use core::panic::PanicInfo;\n" -"\n" -"#[panic_handler]\n" -"fn panic(_panic: &PanicInfo) -> ! {\n" -" loop {}\n" -"}\n" -"```" -msgstr "" -"```rust,editable,compile_fail\n" -"#![no_main]\n" -"#![no_std]\n" -"\n" -"use core::panic::PanicInfo;\n" -"\n" -"#[panic_handler]\n" -"fn panic(_panic: &PanicInfo) -> ! {\n" -" loop {}\n" -"}\n" -"```" - #: src/bare-metal/minimal.md:17 msgid "This will compile to an empty binary." msgstr "" @@ -12941,40 +11688,6 @@ msgid "" "Cortex M microcontrollers." msgstr "" -#: src/bare-metal/microcontrollers.md:5 -msgid "" -"```rust,editable,compile_fail\n" -"#![no_main]\n" -"#![no_std]\n" -"\n" -"extern crate panic_halt as _;\n" -"\n" -"mod interrupts;\n" -"\n" -"use cortex_m_rt::entry;\n" -"\n" -"#[entry]\n" -"fn main() -> ! {\n" -" loop {}\n" -"}\n" -"```" -msgstr "" -"```rust,editable,compile_fail\n" -"#![no_main]\n" -"#![no_std]\n" -"\n" -"extern crate panic_halt as _;\n" -"\n" -"mod interrupts;\n" -"\n" -"use cortex_m_rt::entry;\n" -"\n" -"#[entry]\n" -"fn main() -> ! {\n" -" loop {}\n" -"}\n" -"```" - #: src/bare-metal/microcontrollers.md:21 msgid "" "Next we'll look at how to access peripherals, with increasing levels of " @@ -13136,16 +11849,6 @@ msgstr "" msgid "Run the example with:" msgstr "" -#: src/bare-metal/microcontrollers/mmio.md:68 -msgid "" -"```sh\n" -"cargo embed --bin mmio\n" -"```" -msgstr "" -"```sh\n" -"cargo embed --bin mmio\n" -"```" - #: src/bare-metal/microcontrollers/pacs.md:1 msgid "Peripheral Access Crates" msgstr "" @@ -13268,16 +11971,6 @@ msgid "" "pac -- -d --no-show-raw-insn` to see the resulting binary." msgstr "" -#: src/bare-metal/microcontrollers/pacs.md:61 -msgid "" -"```sh\n" -"cargo embed --bin pac\n" -"```" -msgstr "" -"```sh\n" -"cargo embed --bin pac\n" -"```" - #: src/bare-metal/microcontrollers/hals.md:1 msgid "HAL crates" msgstr "" @@ -13334,13 +12027,6 @@ msgid "" "STM32, GD32, nRF, NXP, MSP430, AVR and PIC microcontrollers." msgstr "" -#: src/bare-metal/microcontrollers/hals.md:45 -msgid "" -"```sh\n" -"cargo embed --bin hal\n" -"```" -msgstr "" - #: src/bare-metal/microcontrollers/board-support.md:1 msgid "Board support crates" msgstr "" @@ -13351,30 +12037,6 @@ msgid "" "board for convenience." msgstr "" -#: src/bare-metal/microcontrollers/board-support.md:5 -msgid "" -"```rust,editable,compile_fail\n" -"#![no_main]\n" -"#![no_std]\n" -"\n" -"extern crate panic_halt as _;\n" -"\n" -"use cortex_m_rt::entry;\n" -"use microbit::hal::prelude::*;\n" -"use microbit::Board;\n" -"\n" -"#[entry]\n" -"fn main() -> ! {\n" -" let mut board = Board::take().unwrap();\n" -"\n" -" board.display_pins.col1.set_low().unwrap();\n" -" board.display_pins.row1.set_high().unwrap();\n" -"\n" -" loop {}\n" -"}\n" -"```" -msgstr "" - #: src/bare-metal/microcontrollers/board-support.md:28 msgid "" "In this case the board support crate is just providing more useful names, " @@ -13391,13 +12053,6 @@ msgstr "" msgid "`microbit-v2` includes a simple driver for the LED matrix." msgstr "" -#: src/bare-metal/microcontrollers/board-support.md:36 -msgid "" -"```sh\n" -"cargo embed --bin board_support\n" -"```" -msgstr "" - #: src/bare-metal/microcontrollers/type-state.md:1 msgid "The type state pattern" msgstr "" @@ -13658,13 +12313,6 @@ msgstr "" msgid "In one terminal under `src/bare-metal/microcontrollers/examples/`:" msgstr "" -#: src/bare-metal/microcontrollers/debugging.md:15 -msgid "" -"```sh\n" -"cargo embed --bin board_support debug\n" -"```" -msgstr "" - #: src/bare-metal/microcontrollers/debugging.md:19 msgid "In another terminal in the same directory:" msgstr "" @@ -13681,18 +12329,6 @@ msgstr "" msgid "In GDB, try running:" msgstr "" -#: src/bare-metal/microcontrollers/debugging.md:29 -msgid "" -"```gdb\n" -"b src/bin/board_support.rs:29\n" -"b src/bin/board_support.rs:30\n" -"b src/bin/board_support.rs:32\n" -"c\n" -"c\n" -"c\n" -"```" -msgstr "" - #: src/bare-metal/microcontrollers/other-projects.md:1 #: src/bare-metal/aps/other-projects.md:1 msgid "Other projects" @@ -13840,8 +12476,8 @@ msgid "" msgstr "" #: src/exercises/bare-metal/compass.md:26 src/exercises/bare-metal/rtc.md:19 -msgid "`src/main.rs`:" -msgstr "`src/main.rs`:" +msgid "_src/main.rs_:" +msgstr "_src/main.rs_:" #: src/exercises/bare-metal/compass.md:30 msgid "" @@ -13881,7 +12517,7 @@ msgid "" msgstr "" #: src/exercises/bare-metal/compass.md:64 src/exercises/bare-metal/rtc.md:385 -msgid "`Cargo.toml` (you shouldn't need to change this):" +msgid "_Cargo.toml_ (you shouldn't need to change this):" msgstr "" #: src/exercises/bare-metal/compass.md:68 @@ -13905,7 +12541,7 @@ msgid "" msgstr "" #: src/exercises/bare-metal/compass.md:85 -msgid "`Embed.toml` (you shouldn't need to change this):" +msgid "_Embed.toml_ (you shouldn't need to change this):" msgstr "" #: src/exercises/bare-metal/compass.md:89 @@ -13923,7 +12559,7 @@ msgid "" msgstr "" #: src/exercises/bare-metal/compass.md:100 src/exercises/bare-metal/rtc.md:985 -msgid "`.cargo/config.toml` (you shouldn't need to change this):" +msgid "_.cargo/config.toml_ (you shouldn't need to change this):" msgstr "" #: src/exercises/bare-metal/compass.md:104 @@ -13941,25 +12577,11 @@ msgstr "" msgid "See the serial output on Linux with:" msgstr "" -#: src/exercises/bare-metal/compass.md:114 -msgid "" -"```sh\n" -"picocom --baud 115200 --imap lfcrlf /dev/ttyACM0\n" -"```" -msgstr "" - #: src/exercises/bare-metal/compass.md:118 msgid "" "Or on Mac OS something like (the device name may be slightly different):" msgstr "" -#: src/exercises/bare-metal/compass.md:120 -msgid "" -"```sh\n" -"picocom --baud 115200 --imap lfcrlf /dev/tty.usbmodem14502\n" -"```" -msgstr "" - #: src/exercises/bare-metal/compass.md:124 msgid "Use Ctrl+A Ctrl+Q to quit picocom." msgstr "" @@ -14667,76 +13289,6 @@ msgid "" "We can use a struct to represent the memory layout of the UART's registers." msgstr "" -#: src/bare-metal/aps/better-uart/registers.md:5 -msgid "" -"```rust,editable,compile_fail\n" -"#[repr(C, align(4))]\n" -"struct Registers {\n" -" dr: u16,\n" -" _reserved0: [u8; 2],\n" -" rsr: ReceiveStatus,\n" -" _reserved1: [u8; 19],\n" -" fr: Flags,\n" -" _reserved2: [u8; 6],\n" -" ilpr: u8,\n" -" _reserved3: [u8; 3],\n" -" ibrd: u16,\n" -" _reserved4: [u8; 2],\n" -" fbrd: u8,\n" -" _reserved5: [u8; 3],\n" -" lcr_h: u8,\n" -" _reserved6: [u8; 3],\n" -" cr: u16,\n" -" _reserved7: [u8; 3],\n" -" ifls: u8,\n" -" _reserved8: [u8; 3],\n" -" imsc: u16,\n" -" _reserved9: [u8; 2],\n" -" ris: u16,\n" -" _reserved10: [u8; 2],\n" -" mis: u16,\n" -" _reserved11: [u8; 2],\n" -" icr: u16,\n" -" _reserved12: [u8; 2],\n" -" dmacr: u8,\n" -" _reserved13: [u8; 3],\n" -"}\n" -"```" -msgstr "" -"```rust,editable,compile_fail\n" -"#[repr(C, align(4))]\n" -"struct Registers {\n" -" dr: u16,\n" -" _reserved0: [u8; 2],\n" -" rsr: ReceiveStatus,\n" -" _reserved1: [u8; 19],\n" -" fr: Flags,\n" -" _reserved2: [u8; 6],\n" -" ilpr: u8,\n" -" _reserved3: [u8; 3],\n" -" ibrd: u16,\n" -" _reserved4: [u8; 2],\n" -" fbrd: u8,\n" -" _reserved5: [u8; 3],\n" -" lcr_h: u8,\n" -" _reserved6: [u8; 3],\n" -" cr: u16,\n" -" _reserved7: [u8; 3],\n" -" ifls: u8,\n" -" _reserved8: [u8; 3],\n" -" imsc: u16,\n" -" _reserved9: [u8; 2],\n" -" ris: u16,\n" -" _reserved10: [u8; 2],\n" -" mis: u16,\n" -" _reserved11: [u8; 2],\n" -" icr: u16,\n" -" _reserved12: [u8; 2],\n" -" dmacr: u8,\n" -" _reserved13: [u8; 3],\n" -"}\n" -"```" - #: src/bare-metal/aps/better-uart/registers.md:41 msgid "" "[`#[repr(C)]`](https://doc.rust-lang.org/reference/type-layout.html#the-c-" @@ -15236,76 +13788,6 @@ msgid "" "types." msgstr "" -#: src/bare-metal/useful-crates/zerocopy.md:6 -msgid "" -"```rust,editable,compile_fail\n" -"use zerocopy::AsBytes;\n" -"\n" -"#[repr(u32)]\n" -"#[derive(AsBytes, Debug, Default)]\n" -"enum RequestType {\n" -" #[default]\n" -" In = 0,\n" -" Out = 1,\n" -" Flush = 4,\n" -"}\n" -"\n" -"#[repr(C)]\n" -"#[derive(AsBytes, Debug, Default)]\n" -"struct VirtioBlockRequest {\n" -" request_type: RequestType,\n" -" reserved: u32,\n" -" sector: u64,\n" -"}\n" -"\n" -"fn main() {\n" -" let request = VirtioBlockRequest {\n" -" request_type: RequestType::Flush,\n" -" sector: 42,\n" -" ..Default::default()\n" -" };\n" -"\n" -" assert_eq!(\n" -" request.as_bytes(),\n" -" &[4, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0]\n" -" );\n" -"}\n" -"```" -msgstr "" -"```rust,editable,compile_fail\n" -"use zerocopy::AsBytes;\n" -"\n" -"#[repr(u32)]\n" -"#[derive(AsBytes, Debug, Default)]\n" -"enum RequestType {\n" -" #[default]\n" -" In = 0,\n" -" Out = 1,\n" -" Flush = 4,\n" -"}\n" -"\n" -"#[repr(C)]\n" -"#[derive(AsBytes, Debug, Default)]\n" -"struct VirtioBlockRequest {\n" -" request_type: RequestType,\n" -" reserved: u32,\n" -" sector: u64,\n" -"}\n" -"\n" -"fn main() {\n" -" let request = VirtioBlockRequest {\n" -" request_type: RequestType::Flush,\n" -" sector: 42,\n" -" ..Default::default()\n" -" };\n" -"\n" -" assert_eq!(\n" -" request.as_bytes(),\n" -" &[4, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0]\n" -" );\n" -"}\n" -"```" - #: src/bare-metal/useful-crates/zerocopy.md:40 msgid "" "This is not suitable for MMIO (as it doesn't use volatile reads and writes), " @@ -15764,7 +14246,7 @@ msgstr "" #: src/exercises/bare-metal/rtc.md:75 msgid "" -"`src/exceptions.rs` (you should only need to change this for the 3rd part of " +"_src/exceptions.rs_ (you should only need to change this for the 3rd part of " "the exercise):" msgstr "" @@ -15913,7 +14395,7 @@ msgstr "" "```" #: src/exercises/bare-metal/rtc.md:149 -msgid "`src/logger.rs` (you shouldn't need to change this):" +msgid "_src/logger.rs_ (you shouldn't need to change this):" msgstr "" #: src/exercises/bare-metal/rtc.md:153 @@ -16035,7 +14517,7 @@ msgstr "" "```" #: src/exercises/bare-metal/rtc.md:210 -msgid "`src/pl011.rs` (you shouldn't need to change this):" +msgid "_src/pl011.rs_ (you shouldn't need to change this):" msgstr "" #: src/exercises/bare-metal/rtc.md:214 @@ -16417,7 +14899,7 @@ msgid "" msgstr "" #: src/exercises/bare-metal/rtc.md:410 -msgid "`build.rs` (you shouldn't need to change this):" +msgid "_build.rs_ (you shouldn't need to change this):" msgstr "" #: src/exercises/bare-metal/rtc.md:414 @@ -16487,7 +14969,7 @@ msgstr "" "```" #: src/exercises/bare-metal/rtc.md:446 -msgid "`entry.S` (you shouldn't need to change this):" +msgid "_entry.S_ (you shouldn't need to change this):" msgstr "" #: src/exercises/bare-metal/rtc.md:450 @@ -16653,7 +15135,7 @@ msgid "" msgstr "" #: src/exercises/bare-metal/rtc.md:595 -msgid "`exceptions.S` (you shouldn't need to change this):" +msgid "_exceptions.S_ (you shouldn't need to change this):" msgstr "" #: src/exercises/bare-metal/rtc.md:599 @@ -16851,7 +15333,7 @@ msgid "" msgstr "" #: src/exercises/bare-metal/rtc.md:780 -msgid "`idmap.S` (you shouldn't need to change this):" +msgid "_idmap.S_ (you shouldn't need to change this):" msgstr "" #: src/exercises/bare-metal/rtc.md:784 @@ -16904,7 +15386,7 @@ msgid "" msgstr "" #: src/exercises/bare-metal/rtc.md:829 -msgid "`image.ld` (you shouldn't need to change this):" +msgid "_image.ld_ (you shouldn't need to change this):" msgstr "" #: src/exercises/bare-metal/rtc.md:833 @@ -17019,7 +15501,7 @@ msgid "" msgstr "" #: src/exercises/bare-metal/rtc.md:940 -msgid "`Makefile` (you shouldn't need to change this):" +msgid "_Makefile_ (you shouldn't need to change this):" msgstr "" #: src/exercises/bare-metal/rtc.md:944 @@ -18049,15 +16531,6 @@ msgid "" "reqwest/). Create a new Cargo project and `reqwest` it as a dependency with:" msgstr "" -#: src/exercises/concurrency/link-checker.md:11 -msgid "" -"```shell\n" -"cargo new link-checker\n" -"cd link-checker\n" -"cargo add --features blocking,rustls-tls reqwest\n" -"```" -msgstr "" - #: src/exercises/concurrency/link-checker.md:17 msgid "" "If `cargo add` fails with `error: no such subcommand`, then please edit the " @@ -18070,26 +16543,12 @@ msgid "" "rs/scraper/) for that:" msgstr "" -#: src/exercises/concurrency/link-checker.md:22 -msgid "" -"```shell\n" -"cargo add scraper\n" -"```" -msgstr "" - #: src/exercises/concurrency/link-checker.md:26 msgid "" "Finally, we'll need some way of handling errors. We use [`thiserror`]" "(https://docs.rs/thiserror/) for that:" msgstr "" -#: src/exercises/concurrency/link-checker.md:29 -msgid "" -"```shell\n" -"cargo add thiserror\n" -"```" -msgstr "" - #: src/exercises/concurrency/link-checker.md:33 msgid "" "The `cargo add` calls will update the `Cargo.toml` file to look like this:" @@ -18195,13 +16654,6 @@ msgstr "" msgid "Run the code in `src/main.rs` with" msgstr "" -#: src/exercises/concurrency/link-checker.md:122 -msgid "" -"```shell\n" -"cargo run\n" -"```" -msgstr "" - #: src/exercises/concurrency/link-checker.md:128 msgid "" "Use threads to check the links in parallel: send the URLs to be checked to a " @@ -18343,25 +16795,6 @@ msgid "" "doc.rust-lang.org/std/task/enum.Poll.html)." msgstr "" -#: src/async/futures.md:8 -msgid "" -"```rust\n" -"use std::pin::Pin;\n" -"use std::task::Context;\n" -"\n" -"pub trait Future {\n" -" type Output;\n" -" fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll;\n" -"}\n" -"\n" -"pub enum Poll {\n" -" Ready(T),\n" -" Pending,\n" -"}\n" -"```" -msgstr "" - #: src/async/futures.md:23 msgid "" "An async function returns an `impl Future`. It's also possible (but " @@ -19110,28 +17543,6 @@ msgid "" "Instead, add a `timeout_fut` containing that future outside of the `loop`:" msgstr "" -#: src/async/pitfalls/pin.md:79 -msgid "" -"```rust,compile_fail\n" -"let mut timeout_fut = sleep(Duration::from_millis(100));\n" -"loop {\n" -" select! {\n" -" ..,\n" -" _ = timeout_fut => { println!(..); },\n" -" }\n" -"}\n" -"```" -msgstr "" -"```rust,compile_fail\n" -"let mut timeout_fut = sleep(Duration::from_millis(100));\n" -"loop {\n" -" select! {\n" -" ..,\n" -" _ = timeout_fut => { println!(..); },\n" -" }\n" -"}\n" -"```" - #: src/async/pitfalls/pin.md:88 msgid "" "This still doesn't work. Follow the compiler errors, adding `&mut` to the " @@ -19139,28 +17550,6 @@ msgid "" "pin`:" msgstr "" -#: src/async/pitfalls/pin.md:92 -msgid "" -"```rust,compile_fail\n" -"let mut timeout_fut = Box::pin(sleep(Duration::from_millis(100)));\n" -"loop {\n" -" select! {\n" -" ..,\n" -" _ = &mut timeout_fut => { println!(..); },\n" -" }\n" -"}\n" -"```" -msgstr "" -"```rust,compile_fail\n" -"let mut timeout_fut = Box::pin(sleep(Duration::from_millis(100)));\n" -"loop {\n" -" select! {\n" -" ..,\n" -" _ = &mut timeout_fut => { println!(..); },\n" -" }\n" -"}\n" -"```" - #: src/async/pitfalls/pin.md:102 msgid "" "This compiles, but once the timeout expires it is `Poll::Ready` on every " @@ -19546,7 +17935,7 @@ msgid "Create a new Cargo project and add the following dependencies:" msgstr "" #: src/exercises/concurrency/chat-app.md:15 -msgid "`Cargo.toml`:" +msgid "_Cargo.toml_:" msgstr "" #: src/exercises/concurrency/chat-app.md:19 @@ -19628,9 +18017,8 @@ msgid "" msgstr "" #: src/exercises/concurrency/chat-app.md:59 -#: src/exercises/concurrency/solutions-afternoon.md:123 -msgid "`src/bin/server.rs`:" -msgstr "`src/bin/server.rs`:" +msgid "_src/bin/server.rs_:" +msgstr "_src/bin/server.rs_:" #: src/exercises/concurrency/chat-app.md:63 msgid "" @@ -19676,9 +18064,8 @@ msgid "" msgstr "" #: src/exercises/concurrency/chat-app.md:103 -#: src/exercises/concurrency/solutions-afternoon.md:210 -msgid "`src/bin/client.rs`:" -msgstr "`src/bin/client.rs`:" +msgid "_src/bin/client.rs_:" +msgstr "_src/bin/client.rs_:" #: src/exercises/concurrency/chat-app.md:107 msgid "" @@ -19714,24 +18101,10 @@ msgstr "Afvikling af binære filer" msgid "Run the server with:" msgstr "" -#: src/exercises/concurrency/chat-app.md:133 -msgid "" -"```shell\n" -"cargo run --bin server\n" -"```" -msgstr "" - #: src/exercises/concurrency/chat-app.md:137 msgid "and the client with:" msgstr "" -#: src/exercises/concurrency/chat-app.md:139 -msgid "" -"```shell\n" -"cargo run --bin client\n" -"```" -msgstr "" - #: src/exercises/concurrency/chat-app.md:145 msgid "Implement the `handle_connection` function in `src/bin/server.rs`." msgstr "" @@ -19970,13 +18343,6 @@ msgid "" "different or better solution than what is presented here." msgstr "" -#: src/exercises/solutions.md:10 -msgid "" -"**Note:** Please ignore the `// ANCHOR: label` and `// ANCHOR_END: label` " -"comments you see in the solutions. They are there to make it possible to re-" -"use parts of the solutions as the exercises." -msgstr "" - #: src/exercises/day-1/solutions-morning.md:1 msgid "Day 1 Morning Exercises" msgstr "Dag 1 formiddagsøvelser" @@ -19988,23 +18354,7 @@ msgstr "([tilbage til øvelsen](for-loops.md))" #: src/exercises/day-1/solutions-morning.md:7 msgid "" "```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: transpose\n" "fn transpose(matrix: [[i32; 3]; 3]) -> [[i32; 3]; 3] {\n" -" // ANCHOR_END: transpose\n" " let mut result = [[0; 3]; 3];\n" " for i in 0..3 {\n" " for j in 0..3 {\n" @@ -20014,15 +18364,12 @@ msgid "" " return result;\n" "}\n" "\n" -"// ANCHOR: pretty_print\n" "fn pretty_print(matrix: &[[i32; 3]; 3]) {\n" -" // ANCHOR_END: pretty_print\n" " for row in matrix {\n" " println!(\"{row:?}\");\n" " }\n" "}\n" "\n" -"// ANCHOR: tests\n" "#[test]\n" "fn test_transpose() {\n" " let matrix = [\n" @@ -20040,9 +18387,7 @@ msgid "" " ]\n" " );\n" "}\n" -"// ANCHOR_END: tests\n" "\n" -"// ANCHOR: main\n" "fn main() {\n" " let matrix = [\n" " [101, 102, 103], // <-- the comment makes rustfmt add a newline\n" @@ -20060,11 +18405,11 @@ msgid "" "```" msgstr "" -#: src/exercises/day-1/solutions-morning.md:78 +#: src/exercises/day-1/solutions-morning.md:57 msgid "Bonus question" msgstr "Bonusspørgsmål" -#: src/exercises/day-1/solutions-morning.md:80 +#: src/exercises/day-1/solutions-morning.md:59 msgid "" "It requires more advanced concepts. It might seem that we could use a slice-" "of-slices (`&[&[i32]]`) as the input type to transpose and thus make our " @@ -20072,21 +18417,21 @@ msgid "" "return type cannot be `&[&[i32]]` since it needs to own the data you return." msgstr "" -#: src/exercises/day-1/solutions-morning.md:82 +#: src/exercises/day-1/solutions-morning.md:61 msgid "" "You can attempt to use something like `Vec>`, but this doesn't work " "out-of-the-box either: it's hard to convert from `Vec>` to " "`&[&[i32]]` so now you cannot easily use `pretty_print` either." msgstr "" -#: src/exercises/day-1/solutions-morning.md:84 +#: src/exercises/day-1/solutions-morning.md:63 msgid "" "Once we get to traits and generics, we'll be able to use the [`std::convert::" "AsRef`](https://doc.rust-lang.org/std/convert/trait.AsRef.html) trait to " "abstract over anything that can be referenced as a slice." msgstr "" -#: src/exercises/day-1/solutions-morning.md:86 +#: src/exercises/day-1/solutions-morning.md:65 msgid "" "```rust\n" "use std::convert::AsRef;\n" @@ -20116,7 +18461,7 @@ msgid "" "```" msgstr "" -#: src/exercises/day-1/solutions-morning.md:113 +#: src/exercises/day-1/solutions-morning.md:92 msgid "" "In addition, the type itself would not enforce that the child slices are of " "the same length, so such variable could contain an invalid matrix." @@ -20133,23 +18478,7 @@ msgstr "([tilbage til øvelsen](luhn.md))" #: src/exercises/day-1/solutions-afternoon.md:7 msgid "" "```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: luhn\n" "pub fn luhn(cc_number: &str) -> bool {\n" -" // ANCHOR_END: luhn\n" " let mut digits_seen = 0;\n" " let mut sum = 0;\n" " for (i, ch) in cc_number.chars().rev().filter(|&ch| ch != ' ')." @@ -20183,7 +18512,6 @@ msgid "" " );\n" "}\n" "\n" -"// ANCHOR: unit-tests\n" "#[test]\n" "fn test_non_digit_cc_number() {\n" " assert!(!luhn(\"foo\"));\n" @@ -20221,27 +18549,10 @@ msgid "" " assert!(!luhn(\"4539 3195 0343 6476\"));\n" " assert!(!luhn(\"8273 1232 7352 0569\"));\n" "}\n" -"// ANCHOR_END: unit-tests\n" "```" msgstr "" "```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: luhn\n" "pub fn luhn(cc_number: &str) -> bool {\n" -" // ANCHOR_END: luhn\n" " let mut digits_seen = 0;\n" " let mut sum = 0;\n" " for (i, ch) in cc_number.chars().rev().filter(|&ch| ch != ' ')." @@ -20275,7 +18586,6 @@ msgstr "" " );\n" "}\n" "\n" -"// ANCHOR: unit-tests\n" "#[test]\n" "fn test_non_digit_cc_number() {\n" " assert!(!luhn(\"foo\"));\n" @@ -20313,15 +18623,141 @@ msgstr "" " assert!(!luhn(\"4539 3195 0343 6476\"));\n" " assert!(!luhn(\"8273 1232 7352 0569\"));\n" "}\n" -"// ANCHOR_END: unit-tests\n" "```" -#: src/exercises/day-1/solutions-afternoon.md:98 +#: src/exercises/day-1/solutions-afternoon.md:80 msgid "Pattern matching" msgstr "Mønstergenkendelse" -#: src/exercises/day-1/solutions-afternoon.md:100 -msgid "TBD." +#: src/exercises/day-1/solutions-afternoon.md:82 +msgid "" +"```rust\n" +"/// An operation to perform on two subexpressions.\n" +"#[derive(Debug)]\n" +"enum Operation {\n" +" Add,\n" +" Sub,\n" +" Mul,\n" +" Div,\n" +"}\n" +"\n" +"/// An expression, in tree form.\n" +"#[derive(Debug)]\n" +"enum Expression {\n" +" /// An operation on two subexpressions.\n" +" Op {\n" +" op: Operation,\n" +" left: Box,\n" +" right: Box,\n" +" },\n" +"\n" +" /// A literal value\n" +" Value(i64),\n" +"}\n" +"\n" +"/// The result of evaluating an expression.\n" +"#[derive(Debug, PartialEq, Eq)]\n" +"enum Res {\n" +" /// Evaluation was successful, with the given result.\n" +" Ok(i64),\n" +" /// Evaluation failed, with the given error message.\n" +" Err(String),\n" +"}\n" +"// Allow `Ok` and `Err` as shorthands for `Res::Ok` and `Res::Err`.\n" +"use Res::{Err, Ok};\n" +"\n" +"fn eval(e: Expression) -> Res {\n" +" match e {\n" +" Expression::Op { op, left, right } => {\n" +" let left = match eval(*left) {\n" +" Ok(v) => v,\n" +" Err(msg) => return Err(msg),\n" +" };\n" +" let right = match eval(*right) {\n" +" Ok(v) => v,\n" +" Err(msg) => return Err(msg),\n" +" };\n" +" Ok(match op {\n" +" Operation::Add => left + right,\n" +" Operation::Sub => left - right,\n" +" Operation::Mul => left * right,\n" +" Operation::Div => {\n" +" if right == 0 {\n" +" return Err(String::from(\"division by zero\"));\n" +" } else {\n" +" left / right\n" +" }\n" +" }\n" +" })\n" +" }\n" +" Expression::Value(v) => Ok(v),\n" +" }\n" +"}\n" +"\n" +"#[test]\n" +"fn test_value() {\n" +" assert_eq!(eval(Expression::Value(19)), Ok(19));\n" +"}\n" +"\n" +"#[test]\n" +"fn test_sum() {\n" +" assert_eq!(\n" +" eval(Expression::Op {\n" +" op: Operation::Add,\n" +" left: Box::new(Expression::Value(10)),\n" +" right: Box::new(Expression::Value(20)),\n" +" }),\n" +" Ok(30)\n" +" );\n" +"}\n" +"\n" +"#[test]\n" +"fn test_recursion() {\n" +" let term1 = Expression::Op {\n" +" op: Operation::Mul,\n" +" left: Box::new(Expression::Value(10)),\n" +" right: Box::new(Expression::Value(9)),\n" +" };\n" +" let term2 = Expression::Op {\n" +" op: Operation::Mul,\n" +" left: Box::new(Expression::Op {\n" +" op: Operation::Sub,\n" +" left: Box::new(Expression::Value(3)),\n" +" right: Box::new(Expression::Value(4)),\n" +" }),\n" +" right: Box::new(Expression::Value(5)),\n" +" };\n" +" assert_eq!(\n" +" eval(Expression::Op {\n" +" op: Operation::Add,\n" +" left: Box::new(term1),\n" +" right: Box::new(term2),\n" +" }),\n" +" Ok(85)\n" +" );\n" +"}\n" +"\n" +"#[test]\n" +"fn test_error() {\n" +" assert_eq!(\n" +" eval(Expression::Op {\n" +" op: Operation::Div,\n" +" left: Box::new(Expression::Value(99)),\n" +" right: Box::new(Expression::Value(0)),\n" +" }),\n" +" Err(String::from(\"division by zero\"))\n" +" );\n" +"}\n" +"fn main() {\n" +" let expr = Expression::Op {\n" +" op: Operation::Sub,\n" +" left: Box::new(Expression::Value(20)),\n" +" right: Box::new(Expression::Value(10)),\n" +" };\n" +" println!(\"expr: {:?}\", expr);\n" +" println!(\"result: {:?}\", eval(expr));\n" +"}\n" +"```" msgstr "" #: src/exercises/day-2/solutions-morning.md:1 @@ -20339,21 +18775,6 @@ msgstr "([tilbage til øvelsen](book-library.md))" #: src/exercises/day-2/solutions-morning.md:7 msgid "" "```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: setup\n" "struct Library {\n" " books: Vec,\n" "}\n" @@ -20373,65 +18794,37 @@ msgid "" " }\n" "}\n" "\n" -"// Implement the methods below. Update the `self` parameter to\n" -"// indicate the method's required level of ownership over the object:\n" +"// Implement the methods below. Notice how the `self` parameter\n" +"// changes type to indicate the method's required level of ownership\n" +"// over the object:\n" "//\n" "// - `&self` for shared read-only access,\n" "// - `&mut self` for unique and mutable access,\n" "// - `self` for unique access by value.\n" "impl Library {\n" -" // ANCHOR_END: setup\n" "\n" -" // ANCHOR: Library_new\n" " fn new() -> Library {\n" -" // ANCHOR_END: Library_new\n" " Library { books: Vec::new() }\n" " }\n" "\n" -" // ANCHOR: Library_len\n" -" //fn len(self) -> usize {\n" -" // todo!(\"Return the length of `self.books`\")\n" -" //}\n" -" // ANCHOR_END: Library_len\n" " fn len(&self) -> usize {\n" " self.books.len()\n" " }\n" "\n" -" // ANCHOR: Library_is_empty\n" -" //fn is_empty(self) -> bool {\n" -" // todo!(\"Return `true` if `self.books` is empty\")\n" -" //}\n" -" // ANCHOR_END: Library_is_empty\n" " fn is_empty(&self) -> bool {\n" " self.books.is_empty()\n" " }\n" "\n" -" // ANCHOR: Library_add_book\n" -" //fn add_book(self, book: Book) {\n" -" // todo!(\"Add a new book to `self.books`\")\n" -" //}\n" -" // ANCHOR_END: Library_add_book\n" " fn add_book(&mut self, book: Book) {\n" " self.books.push(book)\n" " }\n" "\n" -" // ANCHOR: Library_print_books\n" -" //fn print_books(self) {\n" -" // todo!(\"Iterate over `self.books` and print each book's title and " -"year\")\n" -" //}\n" -" // ANCHOR_END: Library_print_books\n" " fn print_books(&self) {\n" " for book in &self.books {\n" " println!(\"{}, published in {}\", book.title, book.year);\n" " }\n" " }\n" "\n" -" // ANCHOR: Library_oldest_book\n" -" //fn oldest_book(self) -> Option<&Book> {\n" -" // todo!(\"Return a reference to the oldest book (if any)\")\n" -" //}\n" -" // ANCHOR_END: Library_oldest_book\n" " fn oldest_book(&self) -> Option<&Book> {\n" " // Using a closure and a built-in method:\n" " // self.books.iter().min_by_key(|book| book.year)\n" @@ -20448,36 +18841,33 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: main\n" -"// This shows the desired behavior. Uncomment the code below and\n" -"// implement the missing methods. You will need to update the\n" -"// method signatures, including the \"self\" parameter! You may\n" -"// also need to update the variable bindings within main.\n" "fn main() {\n" -" let library = Library::new();\n" +" let mut library = Library::new();\n" "\n" -" //println!(\"The library is empty: library.is_empty() -> {}\", library." -"is_empty());\n" -" //\n" -" //library.add_book(Book::new(\"Lord of the Rings\", 1954));\n" -" //library.add_book(Book::new(\"Alice's Adventures in Wonderland\", " +" println!(\n" +" \"The library is empty: library.is_empty() -> {}\",\n" +" library.is_empty()\n" +" );\n" +"\n" +" library.add_book(Book::new(\"Lord of the Rings\", 1954));\n" +" library.add_book(Book::new(\"Alice's Adventures in Wonderland\", " "1865));\n" -" //\n" -" //println!(\"The library is no longer empty: library.is_empty() -> {}\", " -"library.is_empty());\n" -" //\n" -" //\n" -" //library.print_books();\n" -" //\n" -" //match library.oldest_book() {\n" -" // Some(book) => println!(\"The oldest book is {}\", book.title),\n" -" // None => println!(\"The library is empty!\"),\n" -" //}\n" -" //\n" -" //println!(\"The library has {} books\", library.len());\n" -" //library.print_books();\n" +"\n" +" println!(\n" +" \"The library is no longer empty: library.is_empty() -> {}\",\n" +" library.is_empty()\n" +" );\n" +"\n" +" library.print_books();\n" +"\n" +" match library.oldest_book() {\n" +" Some(book) => println!(\"The oldest book is {}\", book.title),\n" +" None => println!(\"The library is empty!\"),\n" +" }\n" +"\n" +" println!(\"The library has {} books\", library.len());\n" +" library.print_books();\n" "}\n" -"// ANCHOR_END: main\n" "\n" "#[test]\n" "fn test_library_len() {\n" @@ -20533,6 +18923,132 @@ msgid "" "```" msgstr "" +#: src/exercises/day-2/solutions-morning.md:153 +msgid "([back to exercise](health-statistics.md))" +msgstr "([tilbage til øvelsen](health-statistics.md))" + +#: src/exercises/day-2/solutions-morning.md:155 +msgid "" +"```rust\n" +"pub struct User {\n" +" name: String,\n" +" age: u32,\n" +" height: f32,\n" +" visit_count: usize,\n" +" last_blood_pressure: Option<(u32, u32)>,\n" +"}\n" +"\n" +"pub struct Measurements {\n" +" height: f32,\n" +" blood_pressure: (u32, u32),\n" +"}\n" +"\n" +"pub struct HealthReport<'a> {\n" +" patient_name: &'a str,\n" +" visit_count: u32,\n" +" height_change: f32,\n" +" blood_pressure_change: Option<(i32, i32)>,\n" +"}\n" +"\n" +"impl User {\n" +" pub fn new(name: String, age: u32, height: f32) -> Self {\n" +" Self {\n" +" name,\n" +" age,\n" +" height,\n" +" visit_count: 0,\n" +" last_blood_pressure: None,\n" +" }\n" +" }\n" +"\n" +" pub fn name(&self) -> &str {\n" +" &self.name\n" +" }\n" +"\n" +" pub fn age(&self) -> u32 {\n" +" self.age\n" +" }\n" +"\n" +" pub fn height(&self) -> f32 {\n" +" self.height\n" +" }\n" +"\n" +" pub fn doctor_visits(&self) -> u32 {\n" +" self.visit_count as u32\n" +" }\n" +"\n" +" pub fn set_age(&mut self, new_age: u32) {\n" +" self.age = new_age\n" +" }\n" +"\n" +" pub fn set_height(&mut self, new_height: f32) {\n" +" self.height = new_height\n" +" }\n" +"\n" +" pub fn visit_doctor(&mut self, measurements: Measurements) -> " +"HealthReport {\n" +" self.visit_count += 1;\n" +" let bp = measurements.blood_pressure;\n" +" let report = HealthReport {\n" +" patient_name: &self.name,\n" +" visit_count: self.visit_count as u32,\n" +" height_change: measurements.height - self.height,\n" +" blood_pressure_change: match self.last_blood_pressure {\n" +" Some(lbp) => Some((\n" +" bp.0 as i32 - lbp.0 as i32,\n" +" bp.1 as i32 - lbp.1 as i32\n" +" )),\n" +" None => None,\n" +" }\n" +" };\n" +" self.height = measurements.height;\n" +" self.last_blood_pressure = Some(bp);\n" +" report\n" +" }\n" +"}\n" +"\n" +"fn main() {\n" +" let bob = User::new(String::from(\"Bob\"), 32, 155.2);\n" +" println!(\"I'm {} and my age is {}\", bob.name(), bob.age());\n" +"}\n" +"\n" +"#[test]\n" +"fn test_height() {\n" +" let bob = User::new(String::from(\"Bob\"), 32, 155.2);\n" +" assert_eq!(bob.height(), 155.2);\n" +"}\n" +"\n" +"#[test]\n" +"fn test_set_age() {\n" +" let mut bob = User::new(String::from(\"Bob\"), 32, 155.2);\n" +" assert_eq!(bob.age(), 32);\n" +" bob.set_age(33);\n" +" assert_eq!(bob.age(), 33);\n" +"}\n" +"\n" +"#[test]\n" +"fn test_visit() {\n" +" let mut bob = User::new(String::from(\"Bob\"), 32, 155.2);\n" +" assert_eq!(bob.doctor_visits(), 0);\n" +" let report = bob.visit_doctor(Measurements {\n" +" height: 156.1,\n" +" blood_pressure: (120, 80),\n" +" });\n" +" assert_eq!(report.patient_name, \"Bob\");\n" +" assert_eq!(report.visit_count, 1);\n" +" assert_eq!(report.blood_pressure_change, None);\n" +"\n" +" let report = bob.visit_doctor(Measurements {\n" +" height: 156.1,\n" +" blood_pressure: (115, 76),\n" +" });\n" +"\n" +" assert_eq!(report.visit_count, 2);\n" +" assert_eq!(report.blood_pressure_change, Some((-5, -4)));\n" +"}\n" +"```" +msgstr "" + #: src/exercises/day-2/solutions-afternoon.md:1 msgid "Day 2 Afternoon Exercises" msgstr "" @@ -20544,23 +19060,7 @@ msgstr "([tilbage til øvelsen](strings-iterators.md))" #: src/exercises/day-2/solutions-afternoon.md:7 msgid "" "```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: prefix_matches\n" "pub fn prefix_matches(prefix: &str, request_path: &str) -> bool {\n" -" // ANCHOR_END: prefix_matches\n" "\n" " let mut request_segments = request_path.split('/');\n" "\n" @@ -20587,7 +19087,6 @@ msgid "" " // and then returns None indefinitely.\n" "}\n" "\n" -"// ANCHOR: unit-tests\n" "#[test]\n" "fn test_matches_without_wildcard() {\n" " assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers\"));\n" @@ -20624,96 +19123,10 @@ msgid "" " \"/v1/publishers/foo/booksByAuthor\"\n" " ));\n" "}\n" -"// ANCHOR_END: unit-tests\n" "\n" "fn main() {}\n" "```" msgstr "" -"```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: prefix_matches\n" -"pub fn prefix_matches(prefix: &str, request_path: &str) -> bool {\n" -" // ANCHOR_END: prefix_matches\n" -"\n" -" let mut request_segments = request_path.split('/');\n" -"\n" -" for prefix_segment in prefix.split('/') {\n" -" let Some(request_segment) = request_segments.next() else {\n" -" return false;\n" -" };\n" -" if request_segment != prefix_segment && prefix_segment != \"*\" {\n" -" return false;\n" -" }\n" -" }\n" -" true\n" -"\n" -" // Alternatively, Iterator::zip() lets us iterate simultaneously over " -"prefix\n" -" // and request segments. The zip() iterator is finished as soon as one " -"of\n" -" // the source iterators is finished, but we need to iterate over all " -"request\n" -" // segments. A neat trick that makes zip() work is to use map() and " -"chain()\n" -" // to produce an iterator that returns Some(str) for each pattern " -"segments,\n" -" // and then returns None indefinitely.\n" -"}\n" -"\n" -"// ANCHOR: unit-tests\n" -"#[test]\n" -"fn test_matches_without_wildcard() {\n" -" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers\"));\n" -" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers/" -"abc-123\"));\n" -" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers/abc/" -"books\"));\n" -"\n" -" assert!(!prefix_matches(\"/v1/publishers\", \"/v1\"));\n" -" assert!(!prefix_matches(\"/v1/publishers\", \"/v1/publishersBooks\"));\n" -" assert!(!prefix_matches(\"/v1/publishers\", \"/v1/parent/" -"publishers\"));\n" -"}\n" -"\n" -"#[test]\n" -"fn test_matches_with_wildcard() {\n" -" assert!(prefix_matches(\n" -" \"/v1/publishers/*/books\",\n" -" \"/v1/publishers/foo/books\"\n" -" ));\n" -" assert!(prefix_matches(\n" -" \"/v1/publishers/*/books\",\n" -" \"/v1/publishers/bar/books\"\n" -" ));\n" -" assert!(prefix_matches(\n" -" \"/v1/publishers/*/books\",\n" -" \"/v1/publishers/foo/books/book1\"\n" -" ));\n" -"\n" -" assert!(!prefix_matches(\"/v1/publishers/*/books\", \"/v1/" -"publishers\"));\n" -" assert!(!prefix_matches(\n" -" \"/v1/publishers/*/books\",\n" -" \"/v1/publishers/foo/booksByAuthor\"\n" -" ));\n" -"}\n" -"// ANCHOR_END: unit-tests\n" -"\n" -"fn main() {}\n" -"```" #: src/exercises/day-3/solutions-morning.md:1 msgid "Day 3 Morning Exercise" @@ -20726,21 +19139,6 @@ msgstr "([tilbage til øvelsen](simple-gui.md))" #: src/exercises/day-3/solutions-morning.md:7 msgid "" "```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: setup\n" "pub trait Widget {\n" " /// Natural width of `self`.\n" " fn width(&self) -> usize;\n" @@ -20807,19 +19205,14 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR_END: setup\n" "\n" -"// ANCHOR: Window-width\n" "impl Widget for Window {\n" " fn width(&self) -> usize {\n" -" // ANCHOR_END: Window-width\n" " // Add 4 paddings for borders\n" " self.inner_width() + 4\n" " }\n" "\n" -" // ANCHOR: Window-draw_into\n" " fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n" -" // ANCHOR_END: Window-draw_into\n" " let mut inner = String::new();\n" " for widget in &self.widgets {\n" " widget.draw_into(&mut inner);\n" @@ -20840,16 +19233,12 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: Button-width\n" "impl Widget for Button {\n" " fn width(&self) -> usize {\n" -" // ANCHOR_END: Button-width\n" " self.label.width() + 8 // add a bit of padding\n" " }\n" "\n" -" // ANCHOR: Button-draw_into\n" " fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n" -" // ANCHOR_END: Button-draw_into\n" " let width = self.width();\n" " let mut label = String::new();\n" " self.label.draw_into(&mut label);\n" @@ -20862,10 +19251,8 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: Label-width\n" "impl Widget for Label {\n" " fn width(&self) -> usize {\n" -" // ANCHOR_END: Label-width\n" " self.label\n" " .lines()\n" " .map(|line| line.chars().count())\n" @@ -20873,14 +19260,11 @@ msgid "" " .unwrap_or(0)\n" " }\n" "\n" -" // ANCHOR: Label-draw_into\n" " fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n" -" // ANCHOR_END: Label-draw_into\n" " writeln!(buffer, \"{}\", &self.label).unwrap();\n" " }\n" "}\n" "\n" -"// ANCHOR: main\n" "fn main() {\n" " let mut window = Window::new(\"Rust GUI Demo 1.23\");\n" " window.add_widget(Box::new(Label::new(\"This is a small text GUI demo." @@ -20891,42 +19275,23 @@ msgid "" " )));\n" " window.draw();\n" "}\n" -"// ANCHOR_END: main\n" "```" msgstr "" -#: src/exercises/day-3/solutions-morning.md:177 +#: src/exercises/day-3/solutions-morning.md:147 msgid "([back to exercise](points-polygons.md))" msgstr "([tilbage til øvelsen](points-polygons.md))" -#: src/exercises/day-3/solutions-morning.md:179 +#: src/exercises/day-3/solutions-morning.md:149 msgid "" "```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" "#[derive(Debug, Copy, Clone, PartialEq, Eq)]\n" -"// ANCHOR: Point\n" "pub struct Point {\n" -" // ANCHOR_END: Point\n" " x: i32,\n" " y: i32,\n" "}\n" "\n" -"// ANCHOR: Point-impl\n" "impl Point {\n" -" // ANCHOR_END: Point-impl\n" " pub fn new(x: i32, y: i32) -> Point {\n" " Point { x, y }\n" " }\n" @@ -20962,15 +19327,11 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: Polygon\n" "pub struct Polygon {\n" -" // ANCHOR_END: Polygon\n" " points: Vec,\n" "}\n" "\n" -"// ANCHOR: Polygon-impl\n" "impl Polygon {\n" -" // ANCHOR_END: Polygon-impl\n" " pub fn new() -> Polygon {\n" " Polygon { points: Vec::new() }\n" " }\n" @@ -21014,16 +19375,12 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: Circle\n" "pub struct Circle {\n" -" // ANCHOR_END: Circle\n" " center: Point,\n" " radius: i32,\n" "}\n" "\n" -"// ANCHOR: Circle-impl\n" "impl Circle {\n" -" // ANCHOR_END: Circle-impl\n" " pub fn new(center: Point, radius: i32) -> Circle {\n" " Circle { center, radius }\n" " }\n" @@ -21037,12 +19394,10 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: Shape\n" "pub enum Shape {\n" " Polygon(Polygon),\n" " Circle(Circle),\n" "}\n" -"// ANCHOR_END: Shape\n" "\n" "impl From for Shape {\n" " fn from(poly: Polygon) -> Self {\n" @@ -21065,7 +19420,6 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: unit-tests\n" "#[cfg(test)]\n" "mod tests {\n" " use super::*;\n" @@ -21136,7 +19490,6 @@ msgid "" " assert_eq!(perimeters, vec![15.48, 31.42]);\n" " }\n" "}\n" -"// ANCHOR_END: unit-tests\n" "\n" "fn main() {}\n" "```" @@ -21153,21 +19506,6 @@ msgstr "([tilbage til øvelsen](safe-ffi-wrapper.md))" #: src/exercises/day-3/solutions-afternoon.md:7 msgid "" "```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: ffi\n" "mod ffi {\n" " use std::os::raw::{c_char, c_int};\n" " #[cfg(not(target_os = \"macos\"))]\n" @@ -21237,14 +19575,11 @@ msgid "" " path: CString,\n" " dir: *mut ffi::DIR,\n" "}\n" -"// ANCHOR_END: ffi\n" "\n" -"// ANCHOR: DirectoryIterator\n" "impl DirectoryIterator {\n" " fn new(path: &str) -> Result {\n" " // Call opendir and return a Ok value if that worked,\n" " // otherwise return Err with a message.\n" -" // ANCHOR_END: DirectoryIterator\n" " let path = CString::new(path).map_err(|err| format!(\"Invalid path: " "{err}\"))?;\n" " // SAFETY: path.as_ptr() cannot be NULL.\n" @@ -21257,12 +19592,10 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: Iterator\n" "impl Iterator for DirectoryIterator {\n" " type Item = OsString;\n" " fn next(&mut self) -> Option {\n" " // Keep calling readdir until we get a NULL pointer back.\n" -" // ANCHOR_END: Iterator\n" " // SAFETY: self.dir is never NULL.\n" " let dirent = unsafe { ffi::readdir(self.dir) };\n" " if dirent.is_null() {\n" @@ -21277,11 +19610,9 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: Drop\n" "impl Drop for DirectoryIterator {\n" " fn drop(&mut self) {\n" " // Call closedir as needed.\n" -" // ANCHOR_END: Drop\n" " if !self.dir.is_null() {\n" " // SAFETY: self.dir is not NULL.\n" " if unsafe { ffi::closedir(self.dir) } != 0 {\n" @@ -21291,13 +19622,11 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: main\n" "fn main() -> Result<(), String> {\n" " let iter = DirectoryIterator::new(\".\")?;\n" " println!(\"files: {:#?}\", iter.collect::>());\n" " Ok(())\n" "}\n" -"// ANCHOR_END: main\n" "\n" "#[cfg(test)]\n" "mod tests {\n" @@ -21353,21 +19682,6 @@ msgstr "([tilbage til øvelsen](compass.md))" #: src/exercises/bare-metal/solutions-morning.md:7 msgid "" "```rust,compile_fail\n" -"// Copyright 2023 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: top\n" "#![no_main]\n" "#![no_std]\n" "\n" @@ -21375,7 +19689,6 @@ msgid "" "\n" "use core::fmt::Write;\n" "use cortex_m_rt::entry;\n" -"// ANCHOR_END: top\n" "use core::cmp::{max, min};\n" "use lsm303agr::{AccelOutputDataRate, Lsm303agr, MagOutputDataRate};\n" "use microbit::display::blocking::Display;\n" @@ -21389,7 +19702,6 @@ msgid "" "const COMPASS_SCALE: i32 = 30000;\n" "const ACCELEROMETER_SCALE: i32 = 700;\n" "\n" -"// ANCHOR: main\n" "#[entry]\n" "fn main() -> ! {\n" " let board = Board::take().unwrap();\n" @@ -21403,7 +19715,6 @@ msgid "" " );\n" "\n" " // Set up the I2C controller and Inertial Measurement Unit.\n" -" // ANCHOR_END: main\n" " writeln!(serial, \"Setting up IMU...\").unwrap();\n" " let i2c = Twim::new(board.TWIM0, board.i2c_internal.into(), FREQUENCY_A::" "K100);\n" @@ -21420,12 +19731,10 @@ msgid "" " let mut mode = Mode::Compass;\n" " let mut button_pressed = false;\n" "\n" -" // ANCHOR: loop\n" " writeln!(serial, \"Ready.\").unwrap();\n" "\n" " loop {\n" " // Read compass data and log it to the serial port.\n" -" // ANCHOR_END: loop\n" " while !(imu.mag_status().unwrap().xyz_new_data\n" " && imu.accel_status().unwrap().xyz_new_data)\n" " {}\n" @@ -21528,28 +19837,12 @@ msgstr "`main.rs`:" #: src/exercises/bare-metal/solutions-afternoon.md:9 msgid "" "```rust,compile_fail\n" -"// Copyright 2023 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: top\n" "#![no_main]\n" "#![no_std]\n" "\n" "mod exceptions;\n" "mod logger;\n" "mod pl011;\n" -"// ANCHOR_END: top\n" "mod pl031;\n" "\n" "use crate::pl031::Rtc;\n" @@ -21557,7 +19850,6 @@ msgid "" "use arm_gic::{irq_enable, wfi};\n" "use chrono::{TimeZone, Utc};\n" "use core::hint::spin_loop;\n" -"// ANCHOR: imports\n" "use crate::pl011::Uart;\n" "use arm_gic::gicv3::GicV3;\n" "use core::panic::PanicInfo;\n" @@ -21571,14 +19863,12 @@ msgid "" "\n" "/// Base address of the primary PL011 UART.\n" "const PL011_BASE_ADDRESS: *mut u32 = 0x900_0000 as _;\n" -"// ANCHOR_END: imports\n" "\n" "/// Base address of the PL031 RTC.\n" "const PL031_BASE_ADDRESS: *mut u32 = 0x901_0000 as _;\n" "/// The IRQ used by the PL031 RTC.\n" "const PL031_IRQ: IntId = IntId::spi(2);\n" "\n" -"// ANCHOR: main\n" "#[no_mangle]\n" "extern \"C\" fn main(x0: u64, x1: u64, x2: u64, x3: u64) {\n" " // Safe because `PL011_BASE_ADDRESS` is the base address of a PL011 " @@ -21596,7 +19886,6 @@ msgid "" " let mut gic = unsafe { GicV3::new(GICD_BASE_ADDRESS, " "GICR_BASE_ADDRESS) };\n" " gic.setup();\n" -" // ANCHOR_END: main\n" "\n" " // Safe because `PL031_BASE_ADDRESS` is the base address of a PL031 " "device,\n" @@ -21658,7 +19947,6 @@ msgid "" " );\n" " info!(\"Finished waiting\");\n" "\n" -" // ANCHOR: main_end\n" " system_off::().unwrap();\n" "}\n" "\n" @@ -21668,31 +19956,16 @@ msgid "" " system_off::().unwrap();\n" " loop {}\n" "}\n" -"// ANCHOR_END: main_end\n" "```" msgstr "" -#: src/exercises/bare-metal/solutions-afternoon.md:149 +#: src/exercises/bare-metal/solutions-afternoon.md:127 msgid "`pl031.rs`:" msgstr "`pl031.rs`:" -#: src/exercises/bare-metal/solutions-afternoon.md:151 +#: src/exercises/bare-metal/solutions-afternoon.md:129 msgid "" "```rust\n" -"// Copyright 2023 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" "use core::ptr::{addr_of, addr_of_mut};\n" "\n" "#[repr(C, align(4))]\n" @@ -21821,21 +20094,6 @@ msgstr "" #: src/exercises/concurrency/solutions-morning.md:7 msgid "" "```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: Philosopher\n" "use std::sync::{mpsc, Arc, Mutex};\n" "use std::thread;\n" "use std::time::Duration;\n" @@ -21844,29 +20102,23 @@ msgid "" "\n" "struct Philosopher {\n" " name: String,\n" -" // ANCHOR_END: Philosopher\n" " left_fork: Arc>,\n" " right_fork: Arc>,\n" " thoughts: mpsc::SyncSender,\n" "}\n" "\n" -"// ANCHOR: Philosopher-think\n" "impl Philosopher {\n" " fn think(&self) {\n" " self.thoughts\n" " .send(format!(\"Eureka! {} has a new idea!\", &self.name))\n" " .unwrap();\n" " }\n" -" // ANCHOR_END: Philosopher-think\n" "\n" -" // ANCHOR: Philosopher-eat\n" " fn eat(&self) {\n" -" // ANCHOR_END: Philosopher-eat\n" " println!(\"{} is trying to eat\", &self.name);\n" " let left = self.left_fork.lock().unwrap();\n" " let right = self.right_fork.lock().unwrap();\n" "\n" -" // ANCHOR: Philosopher-eat-end\n" " println!(\"{} is eating...\", &self.name);\n" " thread::sleep(Duration::from_millis(10));\n" " }\n" @@ -21876,7 +20128,6 @@ msgid "" " &[\"Socrates\", \"Plato\", \"Aristotle\", \"Thales\", \"Pythagoras\"];\n" "\n" "fn main() {\n" -" // ANCHOR_END: Philosopher-eat-end\n" " let (tx, rx) = mpsc::sync_channel(10);\n" "\n" " let forks = (0..PHILOSOPHERS.len())\n" @@ -21918,34 +20169,19 @@ msgid "" "```" msgstr "" -#: src/exercises/concurrency/solutions-morning.md:104 +#: src/exercises/concurrency/solutions-morning.md:82 msgid "Link Checker" msgstr "Linktjekker" -#: src/exercises/concurrency/solutions-morning.md:106 +#: src/exercises/concurrency/solutions-morning.md:84 msgid "([back to exercise](link-checker.md))" msgstr "([tilbage til øvelsen](link-checker.md))" -#: src/exercises/concurrency/solutions-morning.md:108 +#: src/exercises/concurrency/solutions-morning.md:86 msgid "" "```rust,compile_fail\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" "use std::{sync::Arc, sync::Mutex, sync::mpsc, thread};\n" "\n" -"// ANCHOR: setup\n" "use reqwest::{blocking::Client, Url};\n" "use scraper::{Html, Selector};\n" "use thiserror::Error;\n" @@ -21957,9 +20193,7 @@ msgid "" " #[error(\"bad http response: {0}\")]\n" " BadResponse(String),\n" "}\n" -"// ANCHOR_END: setup\n" "\n" -"// ANCHOR: visit_page\n" "#[derive(Debug)]\n" "struct CrawlCommand {\n" " url: Url,\n" @@ -22000,7 +20234,6 @@ msgid "" " }\n" " Ok(link_urls)\n" "}\n" -"// ANCHOR_END: visit_page\n" "\n" "struct CrawlState {\n" " domain: String,\n" @@ -22132,21 +20365,6 @@ msgstr "" #: src/exercises/concurrency/solutions-afternoon.md:7 msgid "" "```rust,compile_fail\n" -"// Copyright 2023 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: Philosopher\n" "use std::sync::Arc;\n" "use tokio::time;\n" "use tokio::sync::mpsc::{self, Sender};\n" @@ -22156,13 +20374,11 @@ msgid "" "\n" "struct Philosopher {\n" " name: String,\n" -" // ANCHOR_END: Philosopher\n" " left_fork: Arc>,\n" " right_fork: Arc>,\n" " thoughts: Sender,\n" "}\n" "\n" -"// ANCHOR: Philosopher-think\n" "impl Philosopher {\n" " async fn think(&self) {\n" " self.thoughts\n" @@ -22170,12 +20386,9 @@ msgid "" "await\n" " .unwrap();\n" " }\n" -" // ANCHOR_END: Philosopher-think\n" "\n" -" // ANCHOR: Philosopher-eat\n" " async fn eat(&self) {\n" " // Pick up forks...\n" -" // ANCHOR_END: Philosopher-eat\n" " let _first_lock = self.left_fork.lock().await;\n" " // Add a delay before picking the second fork to allow the " "execution\n" @@ -22183,13 +20396,10 @@ msgid "" " time::sleep(time::Duration::from_millis(1)).await;\n" " let _second_lock = self.right_fork.lock().await;\n" "\n" -" // ANCHOR: Philosopher-eat-body\n" " println!(\"{} is eating...\", &self.name);\n" " time::sleep(time::Duration::from_millis(5)).await;\n" -" // ANCHOR_END: Philosopher-eat-body\n" "\n" " // The locks are dropped here\n" -" // ANCHOR: Philosopher-eat-end\n" " }\n" "}\n" "\n" @@ -22198,7 +20408,6 @@ msgid "" "\n" "#[tokio::main]\n" "async fn main() {\n" -" // ANCHOR_END: Philosopher-eat-end\n" " // Create forks\n" " let mut forks = vec![];\n" " (0..PHILOSOPHERS.len()).for_each(|_| forks.push(Arc::new(Mutex::" @@ -22248,28 +20457,17 @@ msgid "" "```" msgstr "" -#: src/exercises/concurrency/solutions-afternoon.md:121 +#: src/exercises/concurrency/solutions-afternoon.md:97 msgid "([back to exercise](chat-app.md))" msgstr "([tilbage til øvelsen](chat-app.md))" -#: src/exercises/concurrency/solutions-afternoon.md:125 +#: src/exercises/concurrency/solutions-afternoon.md:99 +msgid "`src/bin/server.rs`:" +msgstr "`src/bin/server.rs`:" + +#: src/exercises/concurrency/solutions-afternoon.md:101 msgid "" "```rust,compile_fail\n" -"// Copyright 2023 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: setup\n" "use futures_util::sink::SinkExt;\n" "use futures_util::stream::StreamExt;\n" "use std::error::Error;\n" @@ -22277,15 +20475,12 @@ msgid "" "use tokio::net::{TcpListener, TcpStream};\n" "use tokio::sync::broadcast::{channel, Sender};\n" "use tokio_websockets::{Message, ServerBuilder, WebsocketStream};\n" -"// ANCHOR_END: setup\n" "\n" -"// ANCHOR: handle_connection\n" "async fn handle_connection(\n" " addr: SocketAddr,\n" " mut ws_stream: WebsocketStream,\n" " bcast_tx: Sender,\n" ") -> Result<(), Box> {\n" -" // ANCHOR_END: handle_connection\n" "\n" " ws_stream\n" " .send(Message::text(\"Welcome to chat! Type a message\".into()))\n" @@ -22315,7 +20510,6 @@ msgid "" " }\n" " }\n" " }\n" -" // ANCHOR: main\n" "}\n" "\n" "#[tokio::main]\n" @@ -22337,28 +20531,16 @@ msgid "" " });\n" " }\n" "}\n" -"// ANCHOR_END: main\n" "```" msgstr "" -#: src/exercises/concurrency/solutions-afternoon.md:212 +#: src/exercises/concurrency/solutions-afternoon.md:166 +msgid "`src/bin/client.rs`:" +msgstr "`src/bin/client.rs`:" + +#: src/exercises/concurrency/solutions-afternoon.md:168 msgid "" "```rust,compile_fail\n" -"// Copyright 2023 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: setup\n" "use futures_util::stream::StreamExt;\n" "use futures_util::SinkExt;\n" "use http::Uri;\n" @@ -22375,7 +20557,6 @@ msgid "" " let stdin = tokio::io::stdin();\n" " let mut stdin = BufReader::new(stdin).lines();\n" "\n" -" // ANCHOR_END: setup\n" " // Continuous loop for concurrently sending and receiving messages.\n" " loop {\n" " tokio::select! {\n" @@ -22404,9 +20585,3 @@ msgid "" "}\n" "```" msgstr "" - -#~ msgid "Comparison" -#~ msgstr "Sammenligning" - -#~ msgid "Extra Work in Modern C++" -#~ msgstr "Defensiv kopiering i moderne C++"