Merge remote-tracking branch 'origin/pr/383'

This commit is contained in:
Carol (Nichols || Goulding) 2017-01-06 17:42:39 -05:00
commit 9c8014cdcd
16 changed files with 70 additions and 68 deletions

View File

@ -79,9 +79,9 @@ fn main() {
These lines define a *function* in Rust. The `main` function is special: it's These lines define a *function* in Rust. The `main` function is special: it's
the first thing that is run for every executable Rust program. The first line the first thing that is run for every executable Rust program. The first line
says, “Im declaring a function named `main` that takes no arguments and says, “Im declaring a function named `main` that receives no arguments and
returns nothing.” If there were arguments, they would go inside the parentheses, returns nothing.” If there were arguments, the parameter names would go inside
`(` and `)`. the parentheses, `(` and `)`.
Also note that the function body is wrapped in curly braces, `{` and `}`. Rust Also note that the function body is wrapped in curly braces, `{` and `}`. Rust
requires these around all function bodies. It's considered good style to put requires these around all function bodies. It's considered good style to put

View File

@ -127,7 +127,7 @@ fn main() {
``` ```
The `fn` syntax declares a new function, the `()` indicate there are no The `fn` syntax declares a new function, the `()` indicate there are no
arguments, and `{` starts the body of the function. parameters, and `{` starts the body of the function.
As you also learned in Chapter 1, `println!` is a macro that prints a string to As you also learned in Chapter 1, `println!` is a macro that prints a string to
the screen: the screen:

View File

@ -50,10 +50,10 @@ The lines execute in the order in which they appear in the `main` function.
First, the “Hello, world!” message prints, and then `another_function` is First, the “Hello, world!” message prints, and then `another_function` is
called and its message is printed. called and its message is printed.
### Function Arguments ### Function Parameters
Functions can also take arguments. The following rewritten version of Functions can also have parameters. The following rewritten version of
`another_function` shows what arguments look like in Rust: `another_function` shows what parameters look like in Rust:
<span class="filename">Filename: src/main.rs</span> <span class="filename">Filename: src/main.rs</span>
@ -76,18 +76,18 @@ $ cargo run
The value of x is: 5 The value of x is: 5
``` ```
The declaration of `another_function` has one argument named `x`. The type of The declaration of `another_function` has one parameter named `x`. The type of
`x` is specified as `i32`. When `5` is passed to `another_function`, the `x` is specified as `i32`. When `5` is passed as an argument to
`println!` macro puts `5` where the pair of curly braces were in the format `another_function`, the `println!` macro puts `5` where the pair of curly
string. braces were in the format string.
In function signatures, you *must* declare the type. This is a deliberate In function signatures, you *must* declare the type of each parameter. This is
decision in Rusts design: requiring type annotations in function definitions a deliberate decision in Rusts design: requiring type annotations in function
means the compiler almost never needs you to use them elsewhere in the code to definitions means the compiler almost never needs you to use them elsewhere in
figure out what you mean. the code to figure out what you mean.
When you want a function to have multiple arguments, separate them inside the When you want a function to receive multiple arguments, separate the parameters
function signature with commas, like this: inside the function signature with commas, like this:
<span class="filename">Filename: src/main.rs</span> <span class="filename">Filename: src/main.rs</span>
@ -102,10 +102,10 @@ fn another_function(x: i32, y: i32) {
} }
``` ```
This example creates a function with two arguments, both of which are `i32` This example creates a function with two parameters, both of which are `i32`
types. If your function has multiple arguments, the arguments dont need to be types. The function then prints out the values of both of its arguments. Note
the same type, but they just happen to be in this example. The function then that function parameters don't all need to be the same type - they just happen
prints out the values of both of its arguments. to be in this example.
Lets try running this code. Replace the program currently in your *function* Lets try running this code. Replace the program currently in your *function*
projects *src/main.rs* file with the preceding example, and run it using projects *src/main.rs* file with the preceding example, and run it using
@ -119,8 +119,8 @@ The value of x is: 5
The value of y is: 6 The value of y is: 6
``` ```
Because `5` is passed as the `x` argument and `6` is passed as the `y` Because `5` is passed into the `x` parameter and `6` is passed into the `y`
argument, the two strings are printed with these values. parameter, the two strings are printed with these values.
### Function Bodies ### Function Bodies

View File

@ -69,7 +69,7 @@ fn calculate_length(s: &String) -> usize { // s is a reference to a String
``` ```
The scope in which the variable `s` is valid is the same as any function The scope in which the variable `s` is valid is the same as any function
argument's scope, but we dont drop what the reference points to when it goes parameter's scope, but we dont drop what the reference points to when it goes
out of scope because we dont have ownership. Functions that take references as out of scope because we dont have ownership. Functions that take references as
arguments instead of the actual values mean we wont need to return the values arguments instead of the actual values mean we wont need to return the values
in order to give back ownership, since we never had ownership. in order to give back ownership, since we never had ownership.

View File

@ -279,7 +279,7 @@ we defined the fields to be `length` and `width`, both of which have type
`u32`. Then in `main`, we create a particular instance of a `Rectangle` that `u32`. Then in `main`, we create a particular instance of a `Rectangle` that
has a length of 50 and a width of 30. has a length of 50 and a width of 30.
Our `area` function now takes one argument that weve named `rectangle` whose Our `area` function now defines one parameter that weve named `rectangle` whose
type is an immutable borrow of a struct `Rectangle` instance. As we covered in type is an immutable borrow of a struct `Rectangle` instance. As we covered in
Chapter 4, we want to borrow the struct rather than take ownership of it so Chapter 4, we want to borrow the struct rather than take ownership of it so
that `main` keeps its ownership and can continue using `rect1`, so thats why that `main` keeps its ownership and can continue using `rect1`, so thats why

View File

@ -52,7 +52,7 @@ Listing 5-7: Defining an `area` method on the `Rectangle` struct
In order to make the function be defined within the context of `Rectangle`, we In order to make the function be defined within the context of `Rectangle`, we
start an `impl` block (`impl` is short for *implementation*). Then we move the start an `impl` block (`impl` is short for *implementation*). Then we move the
function within the `impl` curly braces, and change the first (and in this function within the `impl` curly braces, and change the first (and in this
case, only) argument to be `self` in the signature and everywhere within the case, only) parameter to be `self` in the signature and everywhere within the
body. Then in `main` where we called the `area` function and passed `rect1` as body. Then in `main` where we called the `area` function and passed `rect1` as
an argument, we can instead use *method syntax* to call the `area` method on an argument, we can instead use *method syntax* to call the `area` method on
our `Rectangle` instance. Method syntax is taking an instance and adding a dot our `Rectangle` instance. Method syntax is taking an instance and adding a dot
@ -69,8 +69,8 @@ Weve chosen `&self` here for the same reason we used `&Rectangle` in the
function version: we dont want to take ownership, and we just want to be able function version: we dont want to take ownership, and we just want to be able
to read the data in the struct, not write to it. If we wanted to be able to to read the data in the struct, not write to it. If we wanted to be able to
change the instance that weve called the method on as part of what the method change the instance that weve called the method on as part of what the method
does, wed put `&mut self` as the first argument instead. Having a method that does, wed put `&mut self` as the first parameter instead. Having a method that
takes ownership of the instance by having just `self` as the first argument is takes ownership of the instance by having just `self` as the first parameter is
rarer; this is usually used when the method transforms `self` into something rarer; this is usually used when the method transforms `self` into something
else and we want to prevent the caller from using the original instance after else and we want to prevent the caller from using the original instance after
the transformation. the transformation.
@ -202,8 +202,9 @@ impl Rectangle {
<!-- Will add ghosting here in libreoffice /Carol --> <!-- Will add ghosting here in libreoffice /Carol -->
If we run this with the `main` from Listing 5-8, we will get our desired output! If we run this with the `main` from Listing 5-8, we will get our desired output!
Methods can take multiple arguments that we add to the signature after the Methods can have multiple parameters that we add to the signature after the
`self` parameter, and those arguments work just like arguments in functions do. `self` parameter, and those parameters work just like parameters in functions
do.
### Associated Functions ### Associated Functions

View File

@ -162,7 +162,7 @@ call this method with `String` values. This signature gives us the clues we
need to understand the tricky bits of the `+` operator. need to understand the tricky bits of the `+` operator.
First of all, `s2` has an `&`, meaning that we are adding a *reference* of the First of all, `s2` has an `&`, meaning that we are adding a *reference* of the
second string to the first string. This is because of the `s` argument in the second string to the first string. This is because of the `s` parameter in the
`add` function: we can only add a `&str` to a `String`, we can't add two `add` function: we can only add a `&str` to a `String`, we can't add two
`String`s together. Remember back in Chapter 4 when we talked about how `String`s together. Remember back in Chapter 4 when we talked about how
`&String` will coerce to `&str`: we write `&s2` so that the `String` will `&String` will coerce to `&str`: we write `&s2` so that the `String` will

View File

@ -225,9 +225,9 @@ First, we define a struct named `Guess` that has a field named `value` that
holds a `u32`. This is where the number will be stored. holds a `u32`. This is where the number will be stored.
Then we implement an associated function named `new` on `Guess` that is a Then we implement an associated function named `new` on `Guess` that is a
constructor of `Guess` values. The `new` function takes one argument named constructor of `Guess` values. The `new` function defines one parameter named
`value` of type `u32` and returns a `Guess`. The code in the body of the `new` `value` of type `u32` and returns a `Guess`. The code in the body of the `new`
function tests the `value` argument to make sure it is between 1 and 100. If function tests the `value` parameter to make sure it is between 1 and 100. If
`value` doesn't pass this test, we call `panic!`, which will alert the `value` doesn't pass this test, we call `panic!`, which will alert the
programmer who is calling this code that they have a bug they need to fix, programmer who is calling this code that they have a bug they need to fix,
since creating a `Guess` with a `value` outside this range would violate the since creating a `Guess` with a `value` outside this range would violate the
@ -236,7 +236,7 @@ might panic should be discussed in its public-facing API documentation; we'll
cover documentation conventions around indicating the possibility of a `panic!` cover documentation conventions around indicating the possibility of a `panic!`
in the API documentation that you create in Chapter 14. If `value` does pass in the API documentation that you create in Chapter 14. If `value` does pass
the test, we create a new `Guess` with its `value` field set to the `value` the test, we create a new `Guess` with its `value` field set to the `value`
argument, and return the `Guess`. parameter, and return the `Guess`.
<!-- I'm not sure if you mean the function that creates the guess type (so <!-- I'm not sure if you mean the function that creates the guess type (so
listing 9-8) or the function that uses the guess type, below. You mean the listing 9-8) or the function that uses the guess type, below. You mean the

View File

@ -113,7 +113,7 @@ fn main() {
} }
``` ```
The function takes an argument, `numbers`, which represents any concrete The function defines a parameter, `numbers`, which represents any concrete
`Vec<i32>` that we might pass into the function. The code in the function `Vec<i32>` that we might pass into the function. The code in the function
definition operates on the `numbers` representation of any `Vec<i32>`. When definition operates on the `numbers` representation of any `Vec<i32>`. When
we call the `largest` function, the code actually runs on the specific values we call the `largest` function, the code actually runs on the specific values

View File

@ -98,7 +98,7 @@ enum OptionalNumber { enum OptionalFloatingPointNumber {
``` ```
There's one problem, though: we've *used* `T`, but not defined it. This would There's one problem, though: we've *used* `T`, but not defined it. This would
be similar to using an argument to a function in the body without declaring it be similar to using a parameter of a function in the body without declaring it
in the signature. We need to tell Rust that we've introduced a generic in the signature. We need to tell Rust that we've introduced a generic
parameter. The syntax to do that is the angle brackets, like this: parameter. The syntax to do that is the angle brackets, like this:
@ -303,7 +303,7 @@ type small if you can.
In a similar way to data structures, we can use the `<>` syntax in function or In a similar way to data structures, we can use the `<>` syntax in function or
method definitions. The angle brackets for type parameters go after the method definitions. The angle brackets for type parameters go after the
function or method name and before the argument list in parentheses: function or method name and before the parameter list in parentheses:
```rust ```rust
fn generic_function<T>(value: T) { fn generic_function<T>(value: T) {

View File

@ -272,7 +272,7 @@ Listing 10-3 referred to it:
help: consider adding a `where T: std::fmt::Display` bound help: consider adding a `where T: std::fmt::Display` bound
``` ```
The `where` syntax moves the trait bounds after the function arguments list. The `where` syntax moves the trait bounds after the function parameters list.
This definition of `show_anything` means the exact same thing as the definition This definition of `show_anything` means the exact same thing as the definition
in Listing 10-8, just said a different way: in Listing 10-8, just said a different way:

View File

@ -152,7 +152,7 @@ smaller scope than `x`, the value it refers to.
Note that we didn't have to name any lifetimes in the code itself; Rust figured Note that we didn't have to name any lifetimes in the code itself; Rust figured
it out for us. One situation in which Rust can't figure out the lifetimes is it out for us. One situation in which Rust can't figure out the lifetimes is
for a function or method when one of the arguments or return values is a for a function or method when one of the parameters or return values is a
reference, except for a few scenarios we'll discuss in the lifetime elision reference, except for a few scenarios we'll discuss in the lifetime elision
section. section.
@ -176,8 +176,8 @@ function, we can't know beforehand exactly all of the arguments that it could
be called with and how long they will be valid for. We have to explain to Rust be called with and how long they will be valid for. We have to explain to Rust
what we expect the lifetime of the argument to be (we'll learn about how what we expect the lifetime of the argument to be (we'll learn about how
to know what you expect the lifetime to be in a bit). This is similar to to know what you expect the lifetime to be in a bit). This is similar to
writing a function that has an argument of a generic type: we don't know what writing a function that has a parameter of a generic type: we don't know what
type the arguments will actually end up being when the function gets called. type the parameters will actually end up being when the function gets called.
Lifetimes are the same idea, but they are generic over the scope of a Lifetimes are the same idea, but they are generic over the scope of a
reference, rather than a type. reference, rather than a type.
@ -365,7 +365,7 @@ would create dangling pointers or otherwise violate memory safety.
### Lifetime Elision ### Lifetime Elision
If every reference has a lifetime, and we need to provide them for functions If every reference has a lifetime, and we need to provide them for functions
that use references as arguments or return values, then why did this function that use references as parameters or return values, then why did this function
from the "String Slices" section of Chapter 4 compile? We haven't annotated any from the "String Slices" section of Chapter 4 compile? We haven't annotated any
lifetimes here, yet Rust happily compiles this function: lifetimes here, yet Rust happily compiles this function:
@ -405,15 +405,15 @@ could be ambiguity. The rules are a very basic set of particular cases, and if
your code fits one of those cases, you don't need to write the lifetimes your code fits one of those cases, you don't need to write the lifetimes
explicitly. Here are the rules: explicitly. Here are the rules:
Lifetimes on function arguments are called *input lifetimes*, and lifetimes on Lifetimes on function parameters are called *input lifetimes*, and lifetimes on
return values are called *output lifetimes*. There's one rule related to how return values are called *output lifetimes*. There's one rule related to how
Rust infers input lifetimes in the absence of explicit annotations: Rust infers input lifetimes in the absence of explicit annotations:
1. Each argument that is a reference and therefore needs a lifetime parameter 1. Each function parameter that is a reference and therefore needs a lifetime
gets its own. In other words, a function with one argument gets one lifetime parameter gets its own. In other words, a function with one parameter gets one
parameter: `fn foo<'a>(x: &'a i32)`, a function with two arguments gets two lifetime parameter: `fn foo<'a>(x: &'a i32)`, a function with two parameters
separate lifetime parameters: `fn foo<'a, 'b>(x: &'a i32, y: &'b i32)`, and gets two separate lifetime parameters:
so on. `fn foo<'a, 'b>(x: &'a i32, y: &'b i32)`, and so on.
And two rules related to output lifetimes: And two rules related to output lifetimes:
@ -443,7 +443,7 @@ any methods where the output type's lifetime is the same as that of the
struct's because of the third elision rule. Here's a struct called `App` that struct's because of the third elision rule. Here's a struct called `App` that
holds a reference to another struct, `Config`, defined elsewhere. The holds a reference to another struct, `Config`, defined elsewhere. The
`append_to_name` method does not need lifetime annotations even though the `append_to_name` method does not need lifetime annotations even though the
method has a reference as an argument and is returning a reference; the method has a reference as a parameter and is returning a reference; the
lifetime of the return value will be the lifetime of `self`: lifetime of the return value will be the lifetime of `self`:
<span class="filename">Filename: src/lib.rs</span> <span class="filename">Filename: src/lib.rs</span>

View File

@ -209,7 +209,7 @@ and includes the custom error message we specified:
src/main.rs:4 src/main.rs:4
``` ```
The two arguments to `assert_eq!` are named "left" and "right" rather than The two parameters to `assert_eq!` are named "left" and "right" rather than
"expected" and "actual"; the order of the value that comes from your code and "expected" and "actual"; the order of the value that comes from your code and
the value hardcoded into your test isn't important. the value hardcoded into your test isn't important.

View File

@ -506,7 +506,7 @@ wrapping. Unlike `unwrap`, if the value is an `Err` value, this method calls a
*closure* which is an anonymous function that we define and pass as an argument *closure* which is an anonymous function that we define and pass as an argument
to `unwrap_or_else`. We'll be covering closures in more detail in Chapter XX; to `unwrap_or_else`. We'll be covering closures in more detail in Chapter XX;
the important part to understand in this case is that `unwrap_or_else` will the important part to understand in this case is that `unwrap_or_else` will
pass the inner value of the `Err` to our closure in the argument `err` that pass the inner value of the `Err` to our closure into the parameter `err` that
appears between the vertical pipes. Using `unwrap_or_else` lets us do some appears between the vertical pipes. Using `unwrap_or_else` lets us do some
custom, non-`panic!` error handling. custom, non-`panic!` error handling.

View File

@ -77,18 +77,18 @@ for that function
<!-- Will add ghosting and wingdings in libreoffice /Carol --> <!-- Will add ghosting and wingdings in libreoffice /Carol -->
Notice that we need an explicit lifetime `'a` declared in the signature of Notice that we need an explicit lifetime `'a` declared in the signature of
`grep` and used with the `contents` argument and the return value. Remember, `grep` and used with the `contents` parameter and the return value. Remember,
lifetime parameters are used to specify which arguments' lifetimes connect to lifetime parameters are used to specify which function parameters' lifetimes
the lifetime of the return value. In this case, we're indicating that the connect to the lifetime of the return value. In this case, we're indicating that
vector we're returning is going to contain string slices that reference slices the vector we're returning is going to contain string slices that reference
of the argument `contents`, as opposed to referencing slices of the argument slices of the parameter `contents`, as opposed to referencing slices of the
`search`. Another way to think about what we're telling Rust is that the data parameter `search`. Another way to think about what we're telling Rust is that
returned by the `grep` function will live as long as the data passed into this the data returned by the `grep` function will live as long as the data passed
function in the `contents` argument. This is important! Given that the data a into this function in the `contents` parameter. This is important! Given that
slice references needs to be valid in order for the reference to be valid, if the data a slice references needs to be valid in order for the reference to be
the compiler thought that we were making string slices of `search` rather than valid, if the compiler thought that we were making string slices of `search`
`contents`, it would do its safety checking incorrectly. If we tried to compile rather than `contents`, it would do its safety checking incorrectly. If we tried
this function without lifetimes, we would get this error: to compile this function without lifetimes, we would get this error:
```text ```text
error[E0106]: missing lifetime specifier error[E0106]: missing lifetime specifier
@ -102,12 +102,13 @@ error[E0106]: missing lifetime specifier
`contents` `contents`
``` ```
Rust can't possibly know which of the two arguments we need, so it needs us to Rust can't possibly know which of the two parameters we need, so it needs us to
tell it. Because `contents` is the argument that contains all of our text and tell it. Because `contents` is the parameter that contains all of our text and
we want to return the parts of that text that match, we know `contents` is the we want to return the parts of that text that match, we know `contents` is the
argument that should be connected to the return value using the lifetime syntax. parameter that should be connected to the return value using the lifetime
syntax.
Connecting arguments to return values in the signature is something that other Connecting parameters to return values in the signature is something that other
programming languages don't make you do, so don't worry if this still feels programming languages don't make you do, so don't worry if this still feels
strange! Knowing how to specify lifetimes gets easier over time, and practice strange! Knowing how to specify lifetimes gets easier over time, and practice
makes perfect. You may want to re-read the above section or go back and compare makes perfect. You may want to re-read the above section or go back and compare

View File

@ -1,7 +1,7 @@
# Patterns # Patterns
We've actually used patterns a few times so far: they're used in `let` We've actually used patterns a few times so far: they're used in `let`
statements, in function arguments, and in the `match` expression. Patterns have statements, in function parameters, and in the `match` expression. Patterns have
a lot more abilities than we have demonstrated so far, so we'll cover some of a lot more abilities than we have demonstrated so far, so we'll cover some of
the most commonly used ones in this section. Any of these abilities work in any the most commonly used ones in this section. Any of these abilities work in any
place where a pattern is used. place where a pattern is used.