mirror of
https://github.com/rust-lang-cn/book-cn.git
synced 2025-02-02 15:28:40 +08:00
Change to not have parens in function names in prose
Unless we're quoting a line of code that actually does call the function. But when we're talking about the definition, don't include the parens.
This commit is contained in:
parent
468e5cc202
commit
6d617aba2a
@ -88,7 +88,7 @@ requires these around all function bodies. It's considered good style to put
|
||||
the opening curly brace on the same line as the function declaration, with one
|
||||
space in between.
|
||||
|
||||
Inside the `main()` function:
|
||||
Inside the `main` function:
|
||||
|
||||
```rust
|
||||
println!("Hello, world!");
|
||||
@ -98,15 +98,15 @@ This line does all of the work in this little program: it prints text to the
|
||||
screen. There are a number of details that are important here. The first is
|
||||
that it’s indented with four spaces, not a tab.
|
||||
|
||||
The second important part is `println!()`. This is calling a Rust *macro*,
|
||||
The second important part is `println!`. This is calling a Rust *macro*,
|
||||
which is how metaprogramming is done in Rust. If it were calling a function
|
||||
instead, it would look like this: `println()` (without the `!`). We'll discuss
|
||||
instead, it would look like this: `println` (without the `!`). We'll discuss
|
||||
Rust macros in more detail in Chapter XX, but for now you just need to know
|
||||
that when you see a `!` that means that you’re calling a macro instead of a
|
||||
normal function.
|
||||
|
||||
Next is `"Hello, world!"` which is a *string*. We pass this string as an
|
||||
argument to `println!()`, which prints the string to the screen. Easy enough!
|
||||
argument to `println!`, which prints the string to the screen. Easy enough!
|
||||
|
||||
The line ends with a semicolon (`;`). The `;` indicates that this expression is
|
||||
over, and the next one is ready to begin. Most lines of Rust code end with a
|
||||
|
@ -117,7 +117,7 @@ the functionality to accept user input.
|
||||
fn main() {
|
||||
```
|
||||
|
||||
As you’ve seen in Chapter 1, the `main()` function is the entry point into the
|
||||
As you’ve seen in Chapter 1, the `main` function is the entry point into the
|
||||
program. The `fn` syntax declares a new function, the `()`s indicate that
|
||||
there are no arguments, and `{` starts the body of the function.
|
||||
|
||||
@ -127,7 +127,7 @@ println!("Guess the number!");
|
||||
println!("Please input your guess.");
|
||||
```
|
||||
|
||||
As we learned in Chapter 1, `println!()` is a macro that prints a string to the
|
||||
As we learned in Chapter 1, `println!` is a macro that prints a string to the
|
||||
screen. This is just a prompt stating what the game is and requesting input from
|
||||
the user.
|
||||
|
||||
@ -164,19 +164,19 @@ let mut bar = 5; // mutable
|
||||
|
||||
So now we know that `let mut guess` will introduce a mutable binding named
|
||||
`guess`, but we have to look at the other side of the `=` for the value it’s
|
||||
bound to: `String::new()`. `String` is a string type, provided by the standard
|
||||
bound to: `String::new`. `String` is a string type, provided by the standard
|
||||
library. A [`String`][string]<!-- ignore --> is a growable, UTF-8 encoded bit
|
||||
of text.
|
||||
|
||||
[string]: ../std/string/struct.String.html
|
||||
|
||||
The `::` syntax in the `::new()` line indicates that `new()` is an *associated
|
||||
The `::` syntax in the `::new` line indicates that `new` is an *associated
|
||||
function* of a particular type. An associated function is a function that is
|
||||
associated with a type, in this case `String`, rather than a particular
|
||||
instance of a `String`. Some languages call this a *static method*.
|
||||
|
||||
This `new()` function creates a new, empty `String`.
|
||||
You’ll find a `new()` function on many types, as it’s a common name for making
|
||||
This `new` function creates a new, empty `String`.
|
||||
You’ll find a `new` function on many types, as it’s a common name for making
|
||||
a new value of some kind.
|
||||
|
||||
So to summarize, the `let mut guess = String::new();` line has created a
|
||||
@ -201,13 +201,13 @@ terminal.
|
||||
[iostdin]: ../std/io/struct.Stdin.html
|
||||
|
||||
The next part, `.read_line(&mut guess)`, calls the
|
||||
[`read_line()`][read_line]<!-- ignore --> method on the standard input handle
|
||||
to get input from the user. We’re also passing one argument to `read_line()`:
|
||||
[`read_line`][read_line]<!-- ignore --> method on the standard input handle
|
||||
to get input from the user. We’re also passing one argument to `read_line`:
|
||||
`&mut guess`.
|
||||
|
||||
[read_line]: ../std/io/struct.Stdin.html#method.read_line
|
||||
|
||||
The job of `read_line()` is to take whatever the user types into standard input
|
||||
The job of `read_line` is to take whatever the user types into standard input
|
||||
and place that into a string, so it takes that string as an argument. The
|
||||
string argument needs to be mutable so that the method can change the string's
|
||||
content by adding the user input.
|
||||
@ -243,7 +243,7 @@ calls. Now let's see what this line does.
|
||||
|
||||
### Handling Potential Failure with the `Result` Type
|
||||
|
||||
We mentioned that `read_line()` puts what the user types into the string we
|
||||
We mentioned that `read_line` puts what the user types into the string we
|
||||
pass it, but it also returns a value: in this case, an
|
||||
[`io::Result`][ioresult]<!-- ignore -->. Rust has a number of types named
|
||||
`Result` in its standard library: a generic [`Result`][result]<!-- ignore -->,
|
||||
@ -266,19 +266,19 @@ or why the operation failed.
|
||||
|
||||
The purpose of these `Result` types is to encode error handling information.
|
||||
Values of the `Result` type, like any type, have methods defined on them. In
|
||||
this case, `io::Result` has an [`expect()` method][expect]<!-- ignore --> that
|
||||
we can call. If this instance of `io::Result` is an `Err` value, `expect()`
|
||||
this case, `io::Result` has an [`expect` method][expect]<!-- ignore --> that
|
||||
we can call. If this instance of `io::Result` is an `Err` value, `expect`
|
||||
will cause our program to crash and display the message that we passed as an
|
||||
argument to `expect()`. In this case, if the `read_line()` method returns an
|
||||
argument to `expect`. In this case, if the `read_line` method returns an
|
||||
`Err`, it would likely be the result of an error coming from the underlying
|
||||
operating system. If this instance of `io::Result` is an `Ok` value, `expect()`
|
||||
operating system. If this instance of `io::Result` is an `Ok` value, `expect`
|
||||
will take the return value that `Ok` is holding and return just that value to
|
||||
us so that we can use it. In this case, that value will be what the user
|
||||
entered into standard input.
|
||||
|
||||
[expect]: ../std/result/enum.Result.html#method.expect
|
||||
|
||||
If we don't call `expect()`, our program will compile, but we’ll get a warning:
|
||||
If we don't call `expect`, our program will compile, but we’ll get a warning:
|
||||
|
||||
```bash
|
||||
$ cargo build
|
||||
@ -292,10 +292,10 @@ src/main.rs:10 io::stdin().read_line(&mut guess);
|
||||
Rust warns that we haven’t used the `Result` value, telling us that we
|
||||
haven’t handled a possible error. The right way to suppress the warning is to
|
||||
actually write error handling, but if we just want to crash the program when a
|
||||
problem occurs, we can use `expect()`. We’ll save recovering from errors for a
|
||||
problem occurs, we can use `expect`. We’ll save recovering from errors for a
|
||||
future project.
|
||||
|
||||
### Printing Values with `println!()` Placeholders
|
||||
### Printing Values with `println!` Placeholders
|
||||
|
||||
There’s only one line of this first example left, aside from the closing curly
|
||||
brace:
|
||||
@ -308,7 +308,7 @@ This prints out the string we saved our input in. The `{}`s are a placeholder:
|
||||
think of `{}` as little crab pincers, holding a value in place. You can print
|
||||
more than one value this way: the first `{}` holds the first value listed after
|
||||
the format string, the second set holds the second value, and so on. Printing
|
||||
out multiple values in one call to `println!()` would then look like this:
|
||||
out multiple values in one call to `println!` would then look like this:
|
||||
|
||||
```rust
|
||||
let x = 5;
|
||||
@ -538,12 +538,12 @@ let secret_number = rand::thread_rng().gen_range(1, 101);
|
||||
println!("The secret number is: {}", secret_number);
|
||||
```
|
||||
|
||||
The `rand::thread_rng()` function will give us the particular random number
|
||||
The `rand::thread_rng` function will give us the particular random number
|
||||
generator that we're going to use: one that is local to our current thread of
|
||||
execution and seeded by the operating system. Next, we call the `gen_range()`
|
||||
execution and seeded by the operating system. Next, we call the `gen_range`
|
||||
method on our random number generator. This method is defined by the `Rng`
|
||||
trait that we brought into scope with the `use rand::Rng` statement above. The
|
||||
`gen_range()` method takes two numbers as arguments and generates a random
|
||||
`gen_range` method takes two numbers as arguments and generates a random
|
||||
number between them. It's inclusive on the lower bound but exclusive on the
|
||||
upper bound, so we need `1` and `101` to ask for a number ranging from one to a
|
||||
hundred.
|
||||
@ -638,12 +638,12 @@ match guess.cmp(&secret_number) {
|
||||
}
|
||||
```
|
||||
|
||||
The `cmp()` method compares two values, and can be called on anything that can
|
||||
The `cmp` method compares two values, and can be called on anything that can
|
||||
be compared. It takes a reference to whatever you want to compare with, so here
|
||||
it's comparing our `guess` to our `secret_number`. `cmp()` returns a variant of
|
||||
it's comparing our `guess` to our `secret_number`. `cmp` returns a variant of
|
||||
the `Ordering` enum we imported with the `use` statement earlier. We use a
|
||||
[`match`][match]<!-- ignore --> statement to decide what to do next based on
|
||||
which variant of `Ordering` we got back from our call to `cmp()` with the values
|
||||
which variant of `Ordering` we got back from our call to `cmp` with the values
|
||||
in `guess` and `secret_number`.
|
||||
|
||||
[match]: match.html
|
||||
@ -657,7 +657,7 @@ Chapter XX, respectively.
|
||||
|
||||
Let's walk through an example of what would happen with our `match`. Say that
|
||||
the user has guessed 50, and the randomly-generated secret number this time
|
||||
is 38. So when we compare 50 to 38, the `cmp()` method will return
|
||||
is 38. So when we compare 50 to 38, the `cmp` method will return
|
||||
`Ordering::Greater`, since 50 is greater than 38. `Ordering::Greater` is the
|
||||
value that the `match` statement gets. It looks at the first arm's pattern,
|
||||
`Ordering::Less`, and says nope, the value we have (`Ordering::Greater`) does
|
||||
@ -694,9 +694,9 @@ number; or others. Rust defaults to an `i32`, so that's the type of
|
||||
to infer a different numerical type. The error is because Rust will not compare
|
||||
a string and a number type.
|
||||
|
||||
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; to your `fn main()` body, add the following two lines:
|
||||
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; to your `main` function body, add the following two lines:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
@ -751,15 +751,15 @@ come up with two unique bindings, like `guess_str` and `guess` or something
|
||||
|
||||
We bind `guess` to the expression `guess.trim().parse()`. The `guess` in the
|
||||
expression refers to the original `guess` that was a `String` with our input in
|
||||
it. The `trim()` method on `String`s will eliminate any whitespace at the
|
||||
it. The `trim` method on `String`s will eliminate any whitespace at the
|
||||
beginning and end. Our `u32` can only contain numerical characters, but we have
|
||||
to press the return key to satisfy `read_line()`. When we press the return
|
||||
to press the return key to satisfy `read_line`. When we press the return
|
||||
key, it introduces a newline character. For example, if we type `5` and hit
|
||||
return, `guess` looks like this: `5\n`. The `\n` represents "newline", the
|
||||
return key. The `trim()` method gets rid of this, leaving our string with only
|
||||
return key. The `trim` method gets rid of this, leaving our string with only
|
||||
the `5`.
|
||||
|
||||
The [`parse()` method on strings][parse]<!-- ignore --> parses a string into
|
||||
The [`parse` method on strings][parse]<!-- ignore --> parses a string into
|
||||
some kind of number. Since this method can parse a variety of number types, we
|
||||
need to tell Rust the exact type of number we want with `let guess: u32`. The
|
||||
colon (`:`) after `guess` tells Rust we’re going to annotate its type. Rust has
|
||||
@ -772,15 +772,15 @@ between two values of the same type!
|
||||
|
||||
[parse]: ../std/primitive.str.html#method.parse
|
||||
|
||||
Our call to `parse()` could quite easily cause an error. If, for example, our
|
||||
Our call to `parse` could quite easily cause an error. If, for example, our
|
||||
string contained `A👍%`, there’d be no way to convert that to a number. Because
|
||||
it might fail, the `parse()` method returns a `Result` type, much like the
|
||||
`read_line()` method does that we discussed earlier. We're going to treat this
|
||||
`Result` the same way by using the `expect()` method again. If `parse()`
|
||||
it might fail, the `parse` method returns a `Result` type, much like the
|
||||
`read_line` method does that we discussed earlier. We're going to treat this
|
||||
`Result` the same way by using the `expect` method again. If `parse`
|
||||
returns an `Err` `Result` variant because it could not create a number from the
|
||||
string, the `expect()` call will crash the game and print the message we give
|
||||
it. If `parse()` can successfully turn the string into a number, it will return
|
||||
the `Ok` variant of `Result`, and `expect()` will return the number that we
|
||||
string, the `expect` call will crash the game and print the message we give
|
||||
it. If `parse` can successfully turn the string into a number, it will return
|
||||
the `Ok` variant of `Result`, and `expect` will return the number that we
|
||||
want that it will take out of the `Ok` value for us.
|
||||
|
||||
|
||||
@ -856,7 +856,7 @@ told it to do: ask for another guess forever! It doesn't seem like we can quit!
|
||||
|
||||
We could always halt the program by using the keyboard shortcut `control-c`.
|
||||
There's another way to escape the insatiable monster we've created, though,
|
||||
that can be found in our discussion about `parse()`: if we give a non-number
|
||||
that can be found in our discussion about `parse`: if we give a non-number
|
||||
answer, the program will crash. We can use that to quit! Observe:
|
||||
|
||||
```bash
|
||||
@ -935,7 +935,7 @@ fn main() {
|
||||
|
||||
By adding the `break` line after `You win!`, we’ll exit the loop when we guess
|
||||
the secret number correctly. Exiting the loop also means exiting the program,
|
||||
since the loop is the last thing in `main()`.
|
||||
since the loop is the last thing in `main`.
|
||||
|
||||
#### Handling Invalid Input
|
||||
|
||||
@ -952,25 +952,25 @@ let guess: u32 = match guess.trim().parse() {
|
||||
```
|
||||
|
||||
This is how you generally move from "crash on error" to "actually handle the
|
||||
error": by switching from an `expect()` statement to a `match` statement.
|
||||
Remember that `parse()` returns a `Result` type, and `Result` is an enum that
|
||||
error": by switching from an `expect` statement to a `match` statement.
|
||||
Remember that `parse` returns a `Result` type, and `Result` is an enum that
|
||||
has the variants `Ok` or `Err`. We're going to use a `match` statement here,
|
||||
like we did with the `Ordering` result of the `cmp()` method.
|
||||
like we did with the `Ordering` result of the `cmp` method.
|
||||
|
||||
If `parse()` is able to successfully turn the string into a number, it will
|
||||
If `parse` is able to successfully turn the string into a number, it will
|
||||
return an `Ok` value that contains the resulting number. That `Ok` value will
|
||||
match the first arm's pattern, and the match statement will just return the
|
||||
`num` value that `parse()` produced and put inside the `Ok` value. That number
|
||||
`num` value that `parse` produced and put inside the `Ok` value. That number
|
||||
will end up right where we want it, in the new `guess` binding we're creating.
|
||||
|
||||
If `parse()` is *not* able to turn the string into a number, it will return an
|
||||
If `parse` is *not* able to turn the string into a number, it will return an
|
||||
`Err` value that contains more information about the error. The `Err` value
|
||||
does not match the `Ok(num)` pattern in the first match arm, but it does match
|
||||
the `Err(_)` pattern in the second arm. The `_` is a catch-all value; we're
|
||||
saying we want to match all `Err` values, no matter what information they have
|
||||
inside them. So we execute the second arm's code, `continue`: this means to go
|
||||
to the next iteration of the `loop` and ask for another guess. So we have
|
||||
effectively ignored all errors that `parse()` might hit!
|
||||
effectively ignored all errors that `parse` might hit!
|
||||
|
||||
Now everything in our program should work as we expect it to! Let’s try it:
|
||||
|
||||
|
@ -9,7 +9,7 @@ Something to keep in mind throughout this section: Rust is a *statically typed*
|
||||
language, which means that it must know the types of all bindings at compile
|
||||
time. The compiler can usually infer what type we want to use based on the
|
||||
value and how we use it. When many types are possible, such as when we
|
||||
converted a `String` to a numeric type using `parse()` in the guessing game
|
||||
converted a `String` to a numeric type using `parse` in the guessing game
|
||||
tutorial, we can add a type annotation, like this:
|
||||
|
||||
```rust,ignore
|
||||
|
@ -1,7 +1,7 @@
|
||||
## How Functions Work
|
||||
|
||||
Functions are pervasive in Rust code. We’ve already seen one of the most
|
||||
important functions in the language: the `main()` function that’s the entry
|
||||
important functions in the language: the `main` function that’s the entry
|
||||
point of many programs. We've also seen the `fn` keyword, which allows us to
|
||||
declare new functions.
|
||||
|
||||
@ -28,14 +28,14 @@ after the function name. The curly braces tell the compiler where the function
|
||||
body begins and ends.
|
||||
|
||||
We can call any function we’ve defined by entering its name followed by a pair
|
||||
of parentheses. Since `another_function()` is defined in the program, it can be
|
||||
called from inside the `main()` function. Note that we defined
|
||||
`another_function()` _after_ the `main()` function in our source code; we could
|
||||
of parentheses. Since `another_function` is defined in the program, it can be
|
||||
called from inside the `main` function. Note that we defined
|
||||
`another_function` _after_ the `main` function in our source code; we could
|
||||
have defined it before as well. Rust doesn’t care where you define your
|
||||
functions, only that they are defined somewhere.
|
||||
|
||||
Let’s start a new binary project named `functions` so that we can explore
|
||||
further. Place the `another_function()` example in `src/main.rs` and run it.
|
||||
further. Place the `another_function` example in `src/main.rs` and run it.
|
||||
You should see the following output:
|
||||
|
||||
```bash
|
||||
@ -46,14 +46,14 @@ Hello, world!
|
||||
Another function.
|
||||
```
|
||||
|
||||
The lines execute in the order they appear in the `main()` function. First, our
|
||||
“Hello, world!” message prints, and then `another_function()` is called and its
|
||||
The lines execute in the order they appear in the `main` function. First, our
|
||||
“Hello, world!” message prints, and then `another_function` is called and its
|
||||
message is printed.
|
||||
|
||||
### Function Arguments
|
||||
|
||||
Functions can also take arguments. The following rewritten version of
|
||||
`another_function()` shows what arguments look like in Rust:
|
||||
`another_function` shows what arguments look like in Rust:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
@ -76,9 +76,9 @@ $ cargo run
|
||||
The value of x is: 5
|
||||
```
|
||||
|
||||
Since we passed `5` to `another_function()`, the `println!` macro put `5` where
|
||||
Since we passed `5` to `another_function`, the `println!` macro put `5` where
|
||||
the pair of curly braces were in the format string. The declaration of
|
||||
`another_function()` shows that it takes one argument named `x`, and the type
|
||||
`another_function` shows that it takes one argument named `x`, and the type
|
||||
of `x` is `i32`.
|
||||
|
||||
In function signatures, we _must_ declare the type. This is a deliberate
|
||||
@ -252,8 +252,8 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
There are no function calls, macros, or even `let` statements in the `five()`
|
||||
function-- just the number `5` by itself. That's a perfectly valid function in
|
||||
There are no function calls, macros, or even `let` statements in the `five`
|
||||
function: just the number `5` by itself. That's a perfectly valid function in
|
||||
Rust. Note the function's return type, too. Try running this code, and the
|
||||
output should look like this:
|
||||
|
||||
@ -264,18 +264,18 @@ $ cargo run
|
||||
The value of x is: 5
|
||||
```
|
||||
|
||||
The `5` in `five()` is actually the function's return value, which is why the
|
||||
return type is `i32`. Let’s examine this in more detail. There are two
|
||||
important bits. First, the line `let x = five();` in `main()` shows that we can
|
||||
use the return value of a function to initialize a binding.
|
||||
The `5` in the `five` function is actually the function's return value, which
|
||||
is why the return type is `i32`. Let’s examine this in more detail. There are
|
||||
two important bits. First, the line `let x = five();` in `main` shows that we
|
||||
can use the return value of a function to initialize a binding.
|
||||
|
||||
Because the function `five()` returns a `5`, that line is the same as saying:
|
||||
Because the function `five` returns a `5`, that line is the same as saying:
|
||||
|
||||
```rust
|
||||
let x = 5;
|
||||
```
|
||||
|
||||
The second interesting bit is the `five()` function itself. It requires no
|
||||
The second interesting bit is the `five` function itself. It requires no
|
||||
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:
|
||||
|
@ -386,9 +386,8 @@ item from the `a` array but forgot to update the condition to be `while index <
|
||||
remember to change any other code if we changed the number of values in the
|
||||
array.
|
||||
|
||||
If you're wondering about the `.iter()` code in this example, keep reading! We
|
||||
will cover method syntax generally in Chapter XX and iterators specifically in
|
||||
Chapter XX.
|
||||
If you're wondering about `iter` in this example, keep reading! We will cover
|
||||
method syntax generally in Chapter XX and iterators specifically in Chapter XX.
|
||||
|
||||
The safety and conciseness of `for` loops make them the most commonly used loop
|
||||
construct in Rust. Even in situations where you want to run some code a certain
|
||||
@ -397,7 +396,7 @@ Rustaceans would use a `for` loop. The way to do that is using a `Range`, which
|
||||
is a type provided by the standard library that generates numbers starting from
|
||||
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:
|
||||
about, `rev`, to reverse the range:
|
||||
|
||||
Filename: src/main.rs
|
||||
|
||||
|
@ -48,7 +48,7 @@ mod network {
|
||||
This is our first module declaration. As you can see, you use the `mod`
|
||||
keyword, followed by the name of the module, and then a block of code in curly
|
||||
braces. Everything inside this block is inside the namespace `network`. In this
|
||||
case, we have a single function, `connect()`. If we wanted to try and call this
|
||||
case, we have a single function, `connect`. If we wanted to try and call this
|
||||
function from outside the `network` module, we would say `network::connect()`
|
||||
rather than `connect()`.
|
||||
|
||||
@ -67,7 +67,7 @@ mod client {
|
||||
}
|
||||
```
|
||||
|
||||
Now we have a `network::connect()` function and a `client::connect()` function.
|
||||
Now we have a `network::connect` function and a `client::connect` function.
|
||||
|
||||
And you can put modules inside of modules. If you wanted to have `client` be
|
||||
within `network`:
|
||||
@ -84,7 +84,7 @@ mod network {
|
||||
}
|
||||
```
|
||||
|
||||
This gives us `network::connect()` and `network::client::connect()`.
|
||||
This gives us `network::connect` and `network::client::connect`.
|
||||
|
||||
In this way, modules form a tree. The contents of `src/lib.rs` are at the root
|
||||
of the project's tree, and the submodules form the leaves. Here's what our
|
||||
|
@ -49,7 +49,7 @@ functionality is in a library crate, and the executable crate uses that
|
||||
library. This way, other programs can also use the library crate, and it’s also
|
||||
a nice separation of concerns.
|
||||
|
||||
Our binary crate right now just calls our library's `connect()` function from
|
||||
Our binary crate right now just calls our library's `connect` function from
|
||||
the `client` module; we picked that one since it's the first warning in our
|
||||
build output above. Invoking `cargo build` will now give us an error after the
|
||||
warnings:
|
||||
@ -101,7 +101,7 @@ error: function `connect` is private
|
||||
|
||||
Hooray! We have a different error! Yes, different error messages are a cause
|
||||
for celebration. The new error says "function `connect` is private", so let's
|
||||
edit `src/client.rs` to make `client::connect()` public:
|
||||
edit `src/client.rs` to make `client::connect` public:
|
||||
|
||||
Filename: src/client.rs
|
||||
|
||||
@ -128,7 +128,7 @@ warning: function is never used: `connect`, #[warn(dead_code)] on by default
|
||||
| ^
|
||||
```
|
||||
|
||||
It compiled! And the warning about `client::connect()` not being used is gone!
|
||||
It compiled! And the warning about `client::connect` not being used is gone!
|
||||
|
||||
Making functions public isn't the only way to fix unused code warnings: if
|
||||
we *didn't* want these functions to be part of our public API and we got these
|
||||
@ -230,26 +230,26 @@ fn try_me() {
|
||||
```
|
||||
|
||||
Before you try to compile this code, make a guess about which lines in
|
||||
`try_me()` will have errors.
|
||||
`try_me` will have errors.
|
||||
|
||||
Ready? Let's talk through them!
|
||||
|
||||
The `try_me()` function is in the root module of our project. The module named
|
||||
The `try_me` function is in the root module of our project. The module named
|
||||
`outermost` is private, but the second rule says we're allowed to access it
|
||||
since `outermost` is in our current, root module.
|
||||
|
||||
The function call `outermost::middle_function()` will work. `middle_function()`
|
||||
The function call `outermost::middle_function()` will work. `middle_function`
|
||||
is public, and we are accessing it through its parent module, `outermost`,
|
||||
which we just determined we can access in the previous paragraph.
|
||||
|
||||
`outermost::middle_secret_function()` will cause a compilation error.
|
||||
`middle_secret_function()` is private, so the second rule applies. Our current
|
||||
root module is neither the current module of `middle_secret_function()`
|
||||
`middle_secret_function` is private, so the second rule applies. Our current
|
||||
root module is neither the current module of `middle_secret_function`
|
||||
(`outermost` is), nor is it a child module of the current module of
|
||||
`middle_secret_function()`.
|
||||
`middle_secret_function`.
|
||||
|
||||
The module named `inside` is private and has no child modules, so it can only
|
||||
be accessed by its current module, `outermost`. That means the `try_me()`
|
||||
be accessed by its current module, `outermost`. That means the `try_me`
|
||||
function is not allowed to call `outermost::inside::inner_function()` or
|
||||
`outermost::inside::secret_function()`.
|
||||
|
||||
@ -259,7 +259,7 @@ rules to understand why.
|
||||
|
||||
* What if the `inside` module was public?
|
||||
* What if `outside` was public and `inside` was private?
|
||||
* What if, in the body of `inner_function()`, we called
|
||||
* What if, in the body of `inner_function`, we called
|
||||
`::outermost::middle_secret_function()`? (The two colons at the beginning
|
||||
mean that we want to refer to the namespaces starting from the root
|
||||
namespace.)
|
||||
|
@ -125,11 +125,11 @@ mod tests {
|
||||
|
||||
We'll explain more about testing in Chapter XX, but parts of this should make
|
||||
sense now: we have a module named `tests` that lives next to our other modules
|
||||
and contains one function named `it_works()`. Even though there are special
|
||||
and contains one function named `it_works`. Even though there are special
|
||||
annotations, the `tests` module is just another module!
|
||||
|
||||
Since tests are for exercising the code within our library, let's try to call
|
||||
our `client::connect()` function from this `it_works()` function, even though
|
||||
our `client::connect` function from this `it_works` function, even though
|
||||
we're not going to be checking any functionality right now:
|
||||
|
||||
```rust
|
||||
|
@ -24,7 +24,7 @@ fn bar() {
|
||||
```
|
||||
|
||||
This comment would then be interpreted by `rustdoc` as documenting the thing
|
||||
that follows it: `foo()` and `bar()`.
|
||||
that follows it: `foo` and `bar`.
|
||||
|
||||
Because documentation comments have semantic meaning to `rustdoc`, the compiler
|
||||
will pay attention to the placement of your documentation comments. For
|
||||
|
@ -24,7 +24,7 @@ pub use a::namespace::function;
|
||||
Here, the `a` module is not public to users of our library, so neither are its
|
||||
children, even though `namespace` and `function` are public *within* our
|
||||
library. So users of our library couldn't call `a::namespace::function()`
|
||||
themselves. However, since we've re-exported `function()` with `pub use`,
|
||||
`function()` will be public. Users can just call `function()` themselves,
|
||||
themselves. However, since we've re-exported `function` with `pub use`,
|
||||
`function` will be public. Users can just call `function` themselves,
|
||||
directly. This allows us to organize our code internally however we'd like,
|
||||
while presenting a different external interface.
|
||||
|
@ -125,7 +125,7 @@ fn foo<T>(x: T) {
|
||||
}
|
||||
```
|
||||
|
||||
This `foo()` function has one generic parameter, `T`, and takes one argument,
|
||||
This `foo` function has one generic parameter, `T`, and takes one argument,
|
||||
`x`, which has the type `T`. Let's talk a little bit more about what this means.
|
||||
|
||||
|
||||
@ -158,7 +158,7 @@ more advanced features later, this distinction will become more useful.
|
||||
## There's more to the story
|
||||
|
||||
This section covered the basic syntax of generics, but it's not the full story.
|
||||
For example, let's try to implement our `foo()` function: we'll have it print out
|
||||
For example, let's try to implement our `foo` function: we'll have it print out
|
||||
the value of `x`:
|
||||
|
||||
```rust,ignore
|
||||
|
Loading…
Reference in New Issue
Block a user