mirror of
https://github.com/rust-lang-cn/book-cn.git
synced 2025-02-02 23:38:41 +08:00
parent
b6165b32b9
commit
2e76ef730b
@ -36,6 +36,8 @@ than `helloworld.rs`.
|
||||
|
||||
Now open the `main.rs` file you just created, and type the following code:
|
||||
|
||||
Filename: main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
@ -221,6 +223,8 @@ different version control system, or no version control system, by using the
|
||||
Open up `Cargo.toml` in your text editor of choice. It should look something
|
||||
like this:
|
||||
|
||||
Filename: Cargo.toml
|
||||
|
||||
```toml
|
||||
[package]
|
||||
name = "hello_cargo"
|
||||
@ -254,6 +258,8 @@ the next chapter.
|
||||
|
||||
Now let's look at `src/main.rs`:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
@ -300,6 +306,8 @@ Bam! If all goes well, `Hello, world!` should print to the terminal once more.
|
||||
Running `cargo build` for the first time also causes Cargo to create a new file
|
||||
at the top level called `Cargo.lock`, which looks like this:
|
||||
|
||||
Filename: Cargo.lock
|
||||
|
||||
```toml
|
||||
[root]
|
||||
name = "hello_cargo"
|
||||
|
@ -21,6 +21,8 @@ we’re going to be making another binary like in Chapter 1.
|
||||
|
||||
Take a look at the generated `Cargo.toml`:
|
||||
|
||||
Filename: Cargo.toml
|
||||
|
||||
```toml
|
||||
[package]
|
||||
name = "guessing_game"
|
||||
@ -36,6 +38,8 @@ go ahead and fix that.
|
||||
And as we saw in the last chapter, `cargo new` generates a "Hello, world!" for
|
||||
us. Check out `src/main.rs`:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
@ -63,6 +67,8 @@ file.
|
||||
Let’s get to it! The first thing we need to do for our guessing game is
|
||||
allow our player to input a guess. Put this in your `src/main.rs`:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
use std::io;
|
||||
|
||||
@ -320,6 +326,8 @@ the code using `rand`, we need to modify our `Cargo.toml`. Open it up, and
|
||||
add this line at the bottom beneath the `[dependencies]` section header that
|
||||
Cargo created for you:
|
||||
|
||||
Filename: Cargo.toml
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
|
||||
@ -417,6 +425,8 @@ number of sub-packages.
|
||||
|
||||
Let’s get on to actually _using_ `rand`. Here’s our next step:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
extern crate rand;
|
||||
|
||||
@ -502,6 +512,8 @@ You should get different random numbers, and they should all be between 1 and
|
||||
Now that we’ve got user input, let’s compare our guess to the secret number.
|
||||
Here’s part of our next step. It won't quite compile yet though:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
extern crate rand;
|
||||
|
||||
@ -614,6 +626,8 @@ Ultimately, we want to convert the `String` we read as input
|
||||
into a real number type so that we can compare it to the guess numerically. We
|
||||
can do that with two more lines. Here’s our new program:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
extern crate rand;
|
||||
|
||||
@ -715,6 +729,8 @@ change that by adding loops!
|
||||
|
||||
The `loop` keyword gives us an infinite loop. Let’s add that in:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
extern crate rand;
|
||||
|
||||
@ -783,6 +799,8 @@ error: Process didn't exit successfully: `target/debug/guess` (exit code: 101)
|
||||
Ha! `quit` actually quits. As does any other non-number input. Well, this is
|
||||
suboptimal to say the least. First, let’s actually quit when you win the game:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
extern crate rand;
|
||||
|
||||
@ -828,6 +846,8 @@ thing in `main()`. We have another tweak to make: when someone inputs a
|
||||
non-number, we don’t want to quit, we want to ignore it. We can do that
|
||||
like this:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
extern crate rand;
|
||||
|
||||
@ -919,6 +939,8 @@ think of what it is? That’s right, we don’t want to print out the secret
|
||||
number. It was good for testing, but it kind of ruins the game. Here’s our
|
||||
final source:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
extern crate rand;
|
||||
|
||||
|
@ -19,6 +19,8 @@ $ cd bindings
|
||||
|
||||
Then open `src/main.rs` and replace its code with the following:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
fn main() {
|
||||
let x = 5;
|
||||
@ -121,6 +123,8 @@ code will be changing this value.
|
||||
|
||||
For example, change the program you just wrote to the following:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let mut x = 5;
|
||||
@ -157,6 +161,8 @@ after the second binding. This can be useful if you’d like to perform a few
|
||||
transformations on a value, but have the binding be immutable after those
|
||||
transformations have been completed. For example:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let x = 5;
|
||||
|
@ -78,6 +78,8 @@ your code if you suspect floating-point size is a problem in your case.
|
||||
|
||||
Here's an example showing floating-point numbers in action:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let x = 2.0; // f64
|
||||
@ -95,6 +97,8 @@ Rust supports the usual basic mathematic operations you’d expect for all of
|
||||
these number types: addition, subtraction, multiplication, division, and
|
||||
modulo. This code shows how you'd use each one in a `let` statement:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
// addition
|
||||
@ -123,6 +127,8 @@ As in most other programming languages, a boolean type in Rust has two possible
|
||||
values: `true` and `false`. The boolean type in Rust is specified with `bool`.
|
||||
For example:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let t = true;
|
||||
@ -141,6 +147,8 @@ So far we’ve only worked with numbers, but Rust supports letters too. Rust’s
|
||||
`char` type is the language's most primitive alphabetic type, and this code
|
||||
shows one way to use it:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let c = 'z';
|
||||
@ -165,6 +173,8 @@ all unicode code points at *http://www.unicode.org/charts/*.
|
||||
You can work with the bytes of data directly. Byte literals can be created from
|
||||
the ASCII characters using `b` and single quotes:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let byte = b'a';
|
||||
@ -191,6 +201,8 @@ types into one compound type.
|
||||
We create a tuple by writing a comma-separated list of values inside
|
||||
parentheses. Each position in the tuple has a distinct type, as in this example:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let tup: (i32, f64, u8) = (500, 6.4, 1);
|
||||
@ -202,6 +214,8 @@ name `tup` to the entire tuple, emphasizing the fact that a tuple is considered
|
||||
a single compound element. We could then use pattern matching to destructure
|
||||
this tuple value, like this:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let tup: (i32, f64, u8) = (500, 6.4, 1);
|
||||
@ -225,6 +239,8 @@ In addition to destructuring through pattern matching, we can also access a
|
||||
tuple element directly by using a period (`.`) followed by the index of the
|
||||
value we want to access. For example:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let x: (i32, f64, u8) = (500, 6.4, 1);
|
||||
@ -251,6 +267,8 @@ in Rust have a fixed length-- once declared, they cannot grow or shrink in size.
|
||||
In Rust, the values going into an array are written as a comma separated list
|
||||
inside square brackets:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let a = [1, 2, 3, 4, 5];
|
||||
@ -268,6 +286,8 @@ and we'll discuss them in more detail in chapter XX.
|
||||
An array is a single chunk of memory, allocated on the stack. We can access
|
||||
elements of an array using indexing, like this:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let a = [1, 2, 3, 4, 5];
|
||||
@ -289,6 +309,8 @@ values.
|
||||
What happens if you try to access an element of an array past the end of the
|
||||
array? Say we changed our program to:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
fn main() {
|
||||
let a = [1, 2, 3, 4, 5];
|
||||
|
@ -11,6 +11,8 @@ words. (Rust also uses snake case for the names of variable bindings; we just
|
||||
haven't used any variable bindings with enough letters to need underscores
|
||||
yet). Here's a program containing an example function definition:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
@ -63,6 +65,8 @@ message is printed.
|
||||
Functions can also take arguments. The following rewritten version of
|
||||
`another_function()` shows what arguments look like in Rust:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
another_function(5);
|
||||
@ -95,6 +99,8 @@ the code in order to figure out what you mean.
|
||||
When you want a function to have multiple arguments, just separate them inside
|
||||
the function signature with commas, like this:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
another_function(5, 6);
|
||||
@ -144,6 +150,8 @@ evaluate to a resulting value. Let's look at some examples.
|
||||
`Let` bindings are statements. They instruct the program to create a binding
|
||||
name and assign a value to it. `let y = 6;` in this example is a statement:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let y = 6;
|
||||
@ -156,6 +164,8 @@ statement as well.
|
||||
Statements do not return values themselves. Therefore, you can’t assign a `let`
|
||||
binding to another binding, as this code tries to do:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
fn main() {
|
||||
let x = (let y = 6);
|
||||
@ -196,6 +206,8 @@ y = 6;`, `6` is an expression that evaluates to the value `6`. Calling a
|
||||
function is an expression. Calling a macro is an expression. The block that we
|
||||
use to create new scopes, `{}`, is an expression, for example:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let x = 5;
|
||||
@ -236,6 +248,8 @@ the "return value of the function” is synonymous with “the value of the fina
|
||||
expression in the block of the body of a function.” Here's an example of a
|
||||
function that returns a value:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn five() -> i32 {
|
||||
5
|
||||
@ -276,6 +290,8 @@ arguments and defines the type of the return value, but the body of the
|
||||
function is a lonely `5` with no semicolon because it is an expression whose
|
||||
value we want to return. Let's look at another example:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let x = plus_one(5);
|
||||
@ -292,6 +308,8 @@ Running this code will print `The value of x is: 6`. What happens if we put a
|
||||
semicolon at the end of the line containing `x + 1`, changing it from an
|
||||
expression to a statement?
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
fn main() {
|
||||
let x = plus_one(5);
|
||||
|
@ -23,6 +23,8 @@ include `//` on each line, like this:
|
||||
|
||||
Comments can also be placed at the end of lines of code:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let lucky_number = 7; // I’m feeling lucky today.
|
||||
@ -31,6 +33,8 @@ fn main() {
|
||||
|
||||
But you’ll more often see them above, like so:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
// I’m feeling lucky today.
|
||||
|
@ -23,6 +23,8 @@ $ cd branches
|
||||
Write this sample program using `if` and save it in the *branches* directory in
|
||||
`src/main.rs`:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let number = 3;
|
||||
@ -71,6 +73,8 @@ condition was false
|
||||
It’s also worth noting that `condition` here _must_ be a `bool`. To see what
|
||||
happens if the condition isn't a `bool`, try running this code:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
fn main() {
|
||||
let number = 3;
|
||||
@ -102,6 +106,8 @@ not automatically try to convert non-boolean types to a boolean here, unlike
|
||||
languages like Ruby or JavaScript. We must be explicit and always give `if` a
|
||||
`boolean` as its condition. If your intention is for the `if` code block to be run if a number is not equal to `0`, for example, we would change the `if` expression to read:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let number = 3;
|
||||
@ -119,6 +125,8 @@ Running this will print "number was something other than zero".
|
||||
We can have multiple coniditions by combining `if` and `else` in an `else if`
|
||||
expression. For example:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let number = 5;
|
||||
@ -159,6 +167,8 @@ The last detail you need to learn about `if` is that it’s an expression. That
|
||||
means that we can use it on the right hand side of a `let` binding, for
|
||||
instance:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let condition = true;
|
||||
@ -189,6 +199,8 @@ that results from both arms of the `if` must be the same type; in the previous
|
||||
example, they were both `i32` integers. But what happens if the types are
|
||||
mismatched, as in the following example?
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
fn main() {
|
||||
let condition = true;
|
||||
@ -251,6 +263,8 @@ forever or until we explicitly tell it to stop.
|
||||
For an example, change the `src/main.rs` file in your *loops* directory to look
|
||||
like this:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
fn main() {
|
||||
loop {
|
||||
@ -296,6 +310,8 @@ for it, called a `while` loop. Here's an example using `while`: this program
|
||||
loops three times, counting down each time. Finally, after the loop, it prints
|
||||
another message, then exits:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let mut number = 3;
|
||||
@ -319,6 +335,8 @@ this code; otherwise, exit the loop.
|
||||
We could use this `while` construct to loop over the elements of a collection,
|
||||
like an array. For example:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let a = [10, 20, 30, 40, 50];
|
||||
@ -359,6 +377,8 @@ loop.
|
||||
As a more efficient alternative, we can use a `for` loop and execute some code
|
||||
for each item in a collection. A `for` loop looks like this:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let a = [10, 20, 30, 40, 50];
|
||||
@ -393,6 +413,8 @@ one number and ending before another number. Here's what the countdown would
|
||||
look like with a for loop, and using another method we haven't yet talked
|
||||
about, `.rev()`, to reverse the range:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
for number in (1..4).rev() {
|
||||
|
@ -327,6 +327,8 @@ but nothing that requires allocation or is some form of resource is `Copy`. Here
|
||||
|
||||
Passing a value to a function has similar semantics as assigning it:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let s = String::from("hello");
|
||||
@ -351,6 +353,8 @@ Passing a binding to a function will move or copy, just like assignment. Here’
|
||||
the same example, but with some annotations showing where things go into and
|
||||
out of scope:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let s = String::from("hello"); // s goes into scope.
|
||||
@ -383,6 +387,8 @@ and where the ownership rules prevent you from doing so.
|
||||
|
||||
Returning values can also transfer ownership:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let s1 = gives_ownership();
|
||||
@ -406,6 +412,8 @@ fn takes_and_gives_back(a_string: String) -> String {
|
||||
|
||||
With similiar annotations:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let s1 = gives_ownership(); // gives_ownership moves its return
|
||||
@ -446,6 +454,8 @@ also needs to be passed back if we want to use it again, in addition to any
|
||||
data resulting from the body of the function that we might want to return as
|
||||
well. It's _possible_ to return multiple values, using a tuple, like this:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let s1 = String::from("hello");
|
||||
|
@ -3,6 +3,8 @@
|
||||
At the end of the last section, we had some example Rust that wasn’t very
|
||||
good. Here it is again:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let s1 = String::from("hello");
|
||||
@ -25,6 +27,8 @@ function so that we can still use it there, since it was moved when we called
|
||||
|
||||
There is a better way. It looks like this:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let s1 = String::from("hello");
|
||||
@ -92,6 +96,8 @@ you’re done, you have to give it back.
|
||||
Speaking of which, what if you try to modify something you borrow from me? Try
|
||||
this code out. Spoiler alert: it doesn’t work!
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
fn main() {
|
||||
let s = String::from("hello");
|
||||
@ -121,6 +127,8 @@ allowed to modify something we have a reference to.
|
||||
|
||||
We can fix this bug! Just a small tweak:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let mut s = String::from("hello");
|
||||
@ -139,6 +147,8 @@ String`.
|
||||
|
||||
Mutable references have one big restriction, though. This code fails:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
let mut s = String::from("hello");
|
||||
|
||||
@ -219,6 +229,8 @@ out of scope before the reference does.
|
||||
|
||||
Let’s try to create a dangling reference:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
fn main() {
|
||||
let reference_to_nothing = dangle();
|
||||
|
@ -20,6 +20,8 @@ ownership, so this is fine. But what should we return? We don’t really have a
|
||||
way to talk about _part_ of a string. We could return the index of the end of
|
||||
the word, though. Let’s try that:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn first_word(s: &String) -> usize {
|
||||
let bytes = s.as_bytes();
|
||||
@ -76,6 +78,8 @@ it’s only a meaningful number in the context of the `&String`. In other
|
||||
words, because it’s a separate value from the `String`, there’s no guarantee
|
||||
that it will still be valid in the future. Consider this:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
# fn first_word(s: &String) -> usize {
|
||||
# let bytes = s.as_bytes();
|
||||
@ -176,6 +180,8 @@ let slice = &s[..];
|
||||
|
||||
With this in mind, let’s re-write `first_word()` to return a slice:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn first_word(s: &String) -> &str {
|
||||
let bytes = s.as_bytes();
|
||||
@ -205,6 +211,8 @@ We now have a straightforward API that’s much harder to mess up.
|
||||
But what about our error condition from before? Slices also fix that. Using
|
||||
the slice version of `first_word()` will throw an error:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
fn main() {
|
||||
let mut s = String::from("hello world");
|
||||
@ -274,6 +282,8 @@ the ability to talk about full `String`s. And additionally, we can take
|
||||
string slices of string literals too, so this function is more useful, but
|
||||
with no loss of functionality:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
# fn first_word(s: &str) -> &str {
|
||||
# let bytes = s.as_bytes();
|
||||
|
@ -22,6 +22,8 @@ $ cd points
|
||||
Here’s a short program which calculates the distance between two points. Put
|
||||
it into your `src/main.rs`:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let x1 = 0.0;
|
||||
@ -100,6 +102,8 @@ and `(x2, y2)` together.
|
||||
We’ve already discussed one way to do that: tuples. Here’s a version of our
|
||||
program which uses tuples:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let p1 = (0.0, 5.0);
|
||||
@ -173,6 +177,8 @@ let x = p1.x;
|
||||
Let’s convert our program to use our `Point` `struct`. Here’s what it looks
|
||||
like now:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
#[derive(Debug,Copy,Clone)]
|
||||
struct Point {
|
||||
@ -224,6 +230,8 @@ So far, we’ve been printing values using `{}` in a `println!` macro. If we try
|
||||
that with a struct, however, by default, we'll get an error. Say we have the
|
||||
following program:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust,ignore
|
||||
struct Point {
|
||||
x: f64,
|
||||
@ -270,6 +278,8 @@ defined. To ask `println!` to use `Debug` formatting with our `Point`, we add
|
||||
the annotation to derive the trait and include `:?` in the print string, like
|
||||
this:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
#[derive(Debug)]
|
||||
struct Point {
|
||||
|
@ -20,6 +20,8 @@ particularly humble form of pattern.
|
||||
|
||||
Let’s try a more complex pattern. Change our example program to this:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let (x, y) = (5, 6);
|
||||
|
Loading…
Reference in New Issue
Block a user