You've already forked comprehensive-rust
							
							
				mirror of
				https://github.com/google/comprehensive-rust.git
				synced 2025-10-31 08:37:45 +02:00 
			
		
		
		
	Skip some untranslatable code blocks (#1258)
This builds on the work of @dyoo in https://github.com/google/mdbook-i18n-helpers/pull/69: by adding a special `<!-- mdbook-xgettext: skip -->` comment, we can skip the following code block. I also modified a few code blocks to remove translatable text: variable names are not expected to be translated, so it’s fine to have a line with `println!("foo: {foo}")` in the code block. This PR removes 36 messages from the POT file. The number of lines drop by 633 (3%). Part of #1257.
This commit is contained in:
		| @@ -7,6 +7,7 @@ | ||||
|  | ||||
| Array assignment and access: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     let mut a: [i8; 10] = [42; 10]; | ||||
| @@ -17,11 +18,12 @@ fn main() { | ||||
|  | ||||
| Tuple assignment and access: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     let t: (i8, bool) = (7, true); | ||||
|     println!("1st index: {}", t.0); | ||||
|     println!("2nd index: {}", t.1); | ||||
|     println!("t.0: {}", t.0); | ||||
|     println!("t.1: {}", t.1); | ||||
| } | ||||
| ``` | ||||
|  | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| A Rust version of the famous [FizzBuzz](https://en.wikipedia.org/wiki/Fizz_buzz) interview question: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     print_fizzbuzz_to(20); | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| Rust will statically forbid dangling references: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable,compile_fail | ||||
| fn main() { | ||||
|     let ref_x: &i32; | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| Like C++, Rust has references: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     let mut x: i32 = 10; | ||||
|   | ||||
| @@ -24,6 +24,7 @@ There are a few syntaxes which are not shown above: | ||||
|   == "\\\\n"`. You can embed double-quotes by using an equal amount of `#` on | ||||
|   either side of the quotes: | ||||
|  | ||||
|   <!-- mdbook-xgettext: skip --> | ||||
|   ```rust,editable | ||||
|   fn main() { | ||||
|       println!(r#"<a href="link.html">link</a>"#); | ||||
| @@ -33,6 +34,7 @@ There are a few syntaxes which are not shown above: | ||||
|  | ||||
| - Byte strings allow you to create a `&[u8]` value directly: | ||||
|  | ||||
|   <!-- mdbook-xgettext: skip --> | ||||
|   ```rust,editable | ||||
|   fn main() { | ||||
|       println!("{:?}", b"abc"); | ||||
|   | ||||
| @@ -27,6 +27,7 @@ fn main() { | ||||
| * Shadowing looks obscure at first, but is convenient for holding on to values after `.unwrap()`. | ||||
| * The following code demonstrates why the compiler can't simply reuse memory locations when shadowing an immutable variable in a scope, even if the type does not change. | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     let a = 1; | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| A slice gives you a view into a larger collection: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     let mut a: [i32; 6] = [10, 20, 30, 40, 50, 60]; | ||||
|   | ||||
| @@ -8,6 +8,7 @@ cannot be moved or reallocated during the execution of the program. | ||||
| Constant variables are evaluated at compile time and their values are inlined | ||||
| wherever they are used: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| const DIGEST_SIZE: usize = 3; | ||||
| const ZERO: Option<u8> = Some(42); | ||||
| @@ -22,7 +23,7 @@ fn compute_digest(text: &str) -> [u8; DIGEST_SIZE] { | ||||
|  | ||||
| fn main() { | ||||
|     let digest = compute_digest("Hello"); | ||||
|     println!("Digest: {digest:?}"); | ||||
|     println!("digest: {digest:?}"); | ||||
| } | ||||
| ``` | ||||
|  | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| Rust will look at how the variable is _used_ to determine the type: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn takes_u32(x: u32) { | ||||
|     println!("u32: {x}"); | ||||
| @@ -31,6 +32,7 @@ The compiler does the job for us and helps us write more concise code. | ||||
|  | ||||
| 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: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     let mut v = Vec::new(); | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| Rust provides type safety via static typing. Variable bindings are immutable by | ||||
| default: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     let x: i32 = 10; | ||||
|   | ||||
| @@ -4,6 +4,7 @@ A block in Rust contains a sequence of expressions. | ||||
| Each block has a value and a type, | ||||
| which are those of the last expression of the block: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     let x = { | ||||
| @@ -28,13 +29,14 @@ If the last expression ends with `;`, then the resulting value and type is `()`. | ||||
| The same rule is used for functions: the value of the function body is the | ||||
| return value: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn double(x: i32) -> i32 { | ||||
|     x + x | ||||
| } | ||||
|  | ||||
| fn main() { | ||||
|     println!("doubled: {}", double(7)); | ||||
|     println!("double: {}", double(7)); | ||||
| } | ||||
| ``` | ||||
|  | ||||
|   | ||||
| @@ -7,6 +7,7 @@ the next iteration use [`continue`](https://doc.rust-lang.org/reference/expressi | ||||
| Both `continue` and `break` can optionally take a label argument which is used | ||||
| to break out of nested loops: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     let v = vec![10, 20, 30]; | ||||
|   | ||||
| @@ -4,6 +4,7 @@ The [`for` loop](https://doc.rust-lang.org/std/keyword.for.html) is closely | ||||
| related to the [`while let` loop](while-let-expressions.md). It will | ||||
| automatically call `into_iter()` on the expression and then iterate over it: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     let v = vec![10, 20, 30]; | ||||
|   | ||||
| @@ -25,6 +25,7 @@ Rust. | ||||
| * Unlike `match`, `if let` does not support guard clauses for pattern matching. | ||||
| * Since 1.65, a similar [let-else](https://doc.rust-lang.org/rust-by-example/flow_control/let_else.html) construct allows to do a destructuring assignment, or if it fails, execute a block which is required to abort normal control flow (with `panic`/`return`/`break`/`continue`): | ||||
|  | ||||
|    <!-- mdbook-xgettext: skip --> | ||||
|    ```rust,editable | ||||
|    fn main() { | ||||
|        println!("{:?}", second_word_to_upper("foo bar")); | ||||
|   | ||||
| @@ -5,6 +5,7 @@ which creates an endless loop. | ||||
|  | ||||
| Here you must either `break` or `return` to stop the loop: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     let mut x = 10; | ||||
| @@ -18,7 +19,7 @@ fn main() { | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     println!("Final x: {x}"); | ||||
|     println!("x: {x}"); | ||||
| } | ||||
| ``` | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| The [`while` keyword](https://doc.rust-lang.org/reference/expressions/loop-expr.html#predicate-loops) | ||||
| works very similar to other languages: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     let mut x = 10; | ||||
| @@ -13,7 +14,7 @@ fn main() { | ||||
|             3 * x + 1 | ||||
|         }; | ||||
|     } | ||||
|     println!("Final x: {x}"); | ||||
|     println!("x: {x}"); | ||||
| } | ||||
| ``` | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| Like with `if let`, there is a [`while let`](https://doc.rust-lang.org/reference/expressions/loop-expr.html#predicate-pattern-loops) | ||||
| variant which repeatedly tests a value against a pattern: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     let v = vec![10, 20, 30]; | ||||
|   | ||||
| @@ -31,6 +31,7 @@ Key Points: | ||||
|  | ||||
|  * You can control the discriminant if needed (e.g., for compatibility with C): | ||||
|   | ||||
|      <!-- mdbook-xgettext: skip --> | ||||
|      ```rust,editable | ||||
|      #[repr(u32)] | ||||
|      enum Bar { | ||||
| @@ -67,6 +68,7 @@ Key Points: | ||||
|      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. | ||||
|  | ||||
|      <!-- mdbook-xgettext: skip --> | ||||
|      ```rust,editable | ||||
|      use std::mem::transmute; | ||||
|  | ||||
| @@ -77,25 +79,23 @@ Key Points: | ||||
|      } | ||||
|  | ||||
|      fn main() { | ||||
|          // TOTALLY UNSAFE. Rust provides no guarantees about the bitwise | ||||
|          // representation of types. | ||||
|          unsafe { | ||||
|              println!("Bitwise representation of bool"); | ||||
|              println!("bool:"); | ||||
|              dbg_bits!(false, u8); | ||||
|              dbg_bits!(true, u8); | ||||
|  | ||||
|              println!("Bitwise representation of Option<bool>"); | ||||
|              println!("Option<bool>:"); | ||||
|              dbg_bits!(None::<bool>, u8); | ||||
|              dbg_bits!(Some(false), u8); | ||||
|              dbg_bits!(Some(true), u8); | ||||
|  | ||||
|              println!("Bitwise representation of Option<Option<bool>>"); | ||||
|              println!("Option<Option<bool>>:"); | ||||
|              dbg_bits!(Some(Some(false)), u8); | ||||
|              dbg_bits!(Some(Some(true)), u8); | ||||
|              dbg_bits!(Some(None::<bool>), u8); | ||||
|              dbg_bits!(None::<Option<bool>>, u8); | ||||
|  | ||||
|              println!("Bitwise representation of Option<&i32>"); | ||||
|              println!("Option<&i32>:"); | ||||
|              dbg_bits!(None::<&i32>, usize); | ||||
|              dbg_bits!(Some(&0i32), usize); | ||||
|          } | ||||
| @@ -104,6 +104,7 @@ Key Points: | ||||
|  | ||||
|      More complex example if you want to discuss what happens when we chain more than 256 `Option`s together. | ||||
|  | ||||
|      <!-- mdbook-xgettext: skip --> | ||||
|      ```rust,editable | ||||
|      #![recursion_limit = "1000"] | ||||
|  | ||||
|   | ||||
| @@ -8,6 +8,7 @@ let array = [10, 20, 30]; | ||||
|  | ||||
| You can print such an array by asking for its debug representation with `{:?}`: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     let array = [10, 20, 30]; | ||||
| @@ -38,6 +39,7 @@ fn main() { | ||||
| 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): | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```bob | ||||
|            ⎛⎡1 2 3⎤⎞      ⎡1 4 7⎤ | ||||
| "transpose"⎜⎢4 5 6⎥⎟  "=="⎢2 5 8⎥ | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| Rust will not automatically apply _implicit conversions_ between types ([unlike | ||||
| C++][3]). You can see this in a program like this: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable,compile_fail | ||||
| fn multiply(x: i16, y: i16) -> i16 { | ||||
|     x * y | ||||
|   | ||||
| @@ -24,6 +24,7 @@ void say_hello(std::unique_ptr<Person> person) { | ||||
|  | ||||
| Special move constructors are used when passing ownership to a function: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```c++ | ||||
| std::unique_ptr<Person> person = find_person("Carla"); | ||||
| say_hello(std::move(person)); | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| All variable bindings have a _scope_ where they are valid and it is an error to | ||||
| use a variable outside its scope: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable,compile_fail | ||||
| struct Point(i32, i32); | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| Instead of transferring ownership when calling a function, you can let a | ||||
| function _borrow_ the value: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| #[derive(Debug)] | ||||
| struct Point(i32, i32); | ||||
| @@ -27,6 +28,7 @@ fn main() { | ||||
| Notes on stack returns: | ||||
| * Demonstrate that the return from `add` is cheap because the compiler can eliminate the copy operation. Change the above code to print stack addresses and run it on the [Playground] or look at the assembly in [Godbolt](https://rust.godbolt.org/). In the "DEBUG" optimization level, the addresses should change, while they stay the same when changing to the "RELEASE" setting: | ||||
|  | ||||
|   <!-- mdbook-xgettext: skip --> | ||||
|   ```rust,editable | ||||
|   #[derive(Debug)] | ||||
|   struct Point(i32, i32); | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| While move semantics are the default, certain types are copied by default: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     let x = 42; | ||||
| @@ -15,6 +16,7 @@ These types implement the `Copy` trait. | ||||
|  | ||||
| You can opt-in your own types to use copy semantics: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| #[derive(Copy, Clone, Debug)] | ||||
| struct Point(i32, i32); | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| In addition to borrowing its arguments, a function can return a borrowed value: | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| #[derive(Debug)] | ||||
| struct Point(i32, i32); | ||||
| @@ -14,7 +15,7 @@ fn main() { | ||||
|     let p1: Point = Point(10, 10); | ||||
|     let p2: Point = Point(20, 20); | ||||
|     let p3: &Point = left_most(&p1, &p2); | ||||
|     println!("left-most point: {:?}", p3); | ||||
|     println!("p3: {p3:?}"); | ||||
| } | ||||
| ``` | ||||
|  | ||||
| @@ -29,6 +30,7 @@ fn main() { | ||||
| In the above example, try the following: | ||||
|  | ||||
| * Move the declaration of `p2` and `p3` into a new scope (`{ ... }`), resulting in the following code: | ||||
|   <!-- mdbook-xgettext: skip --> | ||||
|   ```rust,ignore | ||||
|   #[derive(Debug)] | ||||
|   struct Point(i32, i32); | ||||
| @@ -44,7 +46,7 @@ In the above example, try the following: | ||||
|           let p2: Point = Point(20, 20); | ||||
|           p3 = left_most(&p1, &p2); | ||||
|       } | ||||
|       println!("left-most point: {:?}", p3); | ||||
|       println!("p3: {p3:?}"); | ||||
|   } | ||||
|   ``` | ||||
|   Note how this does not compile since `p3` outlives `p2`. | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| # Moved Strings in Rust | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable | ||||
| fn main() { | ||||
|     let s1: String = String::from("Rust"); | ||||
|   | ||||
| @@ -5,6 +5,7 @@ Rust puts constraints on the ways you can borrow values: | ||||
| * You can have one or more `&T` values at any given time, _or_ | ||||
| * You can have exactly one `&mut T` value. | ||||
|  | ||||
| <!-- mdbook-xgettext: skip --> | ||||
| ```rust,editable,compile_fail | ||||
| fn main() { | ||||
|     let mut a: i32 = 10; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user