Add Filename annotations where appropriate

Fixes #190.
This commit is contained in:
Carol (Nichols || Goulding) 2016-08-19 13:12:47 -04:00
parent b6165b32b9
commit 2e76ef730b
12 changed files with 146 additions and 0 deletions

View File

@ -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"

View File

@ -21,6 +21,8 @@ were 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.
Lets 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.
Lets get on to actually _using_ `rand`. Heres 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 weve got user input, lets compare our guess to the secret number.
Heres 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. Heres 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. Lets 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, lets 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 dont 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? Thats right, we dont want to print out the secret
number. It was good for testing, but it kind of ruins the game. Heres our
final source:
Filename: src/main.rs
```rust,ignore
extern crate rand;

View File

@ -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 youd 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;

View File

@ -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 youd 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 weve only worked with numbers, but Rust supports letters too. Rusts
`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];

View File

@ -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 cant 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);

View File

@ -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; // Im feeling lucky today.
@ -31,6 +33,8 @@ fn main() {
But youll more often see them above, like so:
Filename: src/main.rs
```rust
fn main() {
// Im feeling lucky today.

View File

@ -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
Its 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 its 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() {

View File

@ -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");

View File

@ -3,6 +3,8 @@
At the end of the last section, we had some example Rust that wasnt 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 @@ youre 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 doesnt 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.
Lets try to create a dangling reference:
Filename: src/main.rs
```rust,ignore
fn main() {
let reference_to_nothing = dangle();

View File

@ -20,6 +20,8 @@ ownership, so this is fine. But what should we return? We dont really have a
way to talk about _part_ of a string. We could return the index of the end of
the word, though. Lets try that:
Filename: src/main.rs
```rust
fn first_word(s: &String) -> usize {
let bytes = s.as_bytes();
@ -76,6 +78,8 @@ its only a meaningful number in the context of the `&String`. In other
words, because its a separate value from the `String`, theres 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, lets 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 thats 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();

View File

@ -22,6 +22,8 @@ $ cd points
Heres 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.
Weve already discussed one way to do that: tuples. Heres 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;
Lets convert our program to use our `Point` `struct`. Heres what it looks
like now:
Filename: src/main.rs
```rust
#[derive(Debug,Copy,Clone)]
struct Point {
@ -224,6 +230,8 @@ So far, weve 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 {

View File

@ -20,6 +20,8 @@ particularly humble form of pattern.
Lets try a more complex pattern. Change our example program to this:
Filename: src/main.rs
```rust
fn main() {
let (x, y) = (5, 6);