Skip to content

Commit

Permalink
Merge pull request #1 from rust-lang/master
Browse files Browse the repository at this point in the history
Merge pull request rust-lang#1951 from mlevesquedion/fix/duck-typing-…
  • Loading branch information
fengjixuchui authored Oct 14, 2019
2 parents 6d3e768 + 7b23a00 commit c58e8b9
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 21 deletions.
11 changes: 6 additions & 5 deletions src/ch09-02-recoverable-errors-with-result.md
Original file line number Diff line number Diff line change
Expand Up @@ -470,13 +470,13 @@ and returns it. Of course, using `fs::read_to_string` doesn’t give us the
opportunity to explain all the error handling, so we did it the longer way
first.

#### The `?` Operator Can Only Be Used in Functions That Return `Result`
#### The `?` Operator Can Be Used in Functions That Return `Result`

The `?` operator can only be used in functions that have a return type of
The `?` operator can be used in functions that have a return type of
`Result`, because it is defined to work in the same way as the `match`
expression we defined in Listing 9-6. The part of the `match` that requires a
return type of `Result` is `return Err(e)`, so the return type of the function
must be a `Result` to be compatible with this `return`.
can be a `Result` to be compatible with this `return`.

Let’s look at what happens if we use the `?` operator in the `main` function,
which you’ll recall has a return type of `()`:
Expand Down Expand Up @@ -505,8 +505,9 @@ error[E0277]: the `?` operator can only be used in a function that returns
```

This error points out that we’re only allowed to use the `?` operator in a
function that returns `Result<T, E>`. When you’re writing code in a function
that doesn’t return `Result<T, E>`, and you want to use `?` when you call other
function that returns `Result` or `Option` or another type that implements
`std::ops::Try`. When you’re writing code in a function
that doesn’t return one of these types, and you want to use `?` when you call other
functions that return `Result<T, E>`, you have two choices to fix this problem.
One technique is to change the return type of your function to be `Result<T,
E>` if you have no restrictions preventing that. The other technique is to use
Expand Down
12 changes: 6 additions & 6 deletions src/ch10-02-traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -611,12 +611,12 @@ reduce duplication but also specify to the compiler that we want the generic
type to have particular behavior. The compiler can then use the trait bound
information to check that all the concrete types used with our code provide the
correct behavior. In dynamically typed languages, we would get an error at
runtime if we called a method on a type that the type didn’t implement. But
Rust moves these errors to compile time so we’re forced to fix the problems
before our code is even able to run. Additionally, we don’t have to write code
that checks for behavior at runtime because we’ve already checked at compile
time. Doing so improves performance without having to give up the flexibility
of generics.
runtime if we called a method on a type which didn’t implement the type which
defines the method. But Rust moves these errors to compile time so we’re forced
to fix the problems before our code is even able to run. Additionally, we don’t
have to write code that checks for behavior at runtime because we’ve already
checked at compile time. Doing so improves performance without having to give
up the flexibility of generics.

Another kind of generic that we’ve already been using is called *lifetimes*.
Rather than ensuring that a type has the behavior we want, lifetimes ensure
Expand Down
17 changes: 9 additions & 8 deletions src/ch17-02-trait-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,14 +275,15 @@ new type and draw it because `SelectBox` implements the `Draw` trait, which
means it implements the `draw` method.

This concept—of being concerned only with the messages a value responds to
rather than the value’s concrete type—is similar to the concept *duck typing*
in dynamically typed languages: if it walks like a duck and quacks like a duck,
then it must be a duck! In the implementation of `run` on `Screen` in Listing
17-5, `run` doesn’t need to know what the concrete type of each component is.
It doesn’t check whether a component is an instance of a `Button` or a
`SelectBox`, it just calls the `draw` method on the component. By specifying
`Box<dyn Draw>` as the type of the values in the `components` vector, we’ve
defined `Screen` to need values that we can call the `draw` method on.
rather than the value’s concrete type—is similar to the concept of *duck
typing* in dynamically typed languages: if it walks like a duck and quacks
like a duck, then it must be a duck! In the implementation of `run` on `Screen`
in Listing 17-5, `run` doesn’t need to know what the concrete type of each
component is. It doesn’t check whether a component is an instance of a `Button`
or a `SelectBox`, it just calls the `draw` method on the component. By
specifying `Box<dyn Draw>` as the type of the values in the `components`
vector, we’ve defined `Screen` to need values that we can call the `draw`
method on.

The advantage of using trait objects and Rust’s type system to write code
similar to code using duck typing is that we never have to check whether a
Expand Down
4 changes: 2 additions & 2 deletions src/ch18-03-pattern-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -711,11 +711,11 @@ fn main() {

match x {
Some(50) => println!("Got 50"),
Some(n) if n == y => println!("Matched, n = {:?}", n),
Some(n) if n == y => println!("Matched, n = {}", n),
_ => println!("Default case, x = {:?}", x),
}

println!("at the end: x = {:?}, y = {:?}", x, y);
println!("at the end: x = {:?}, y = {}", x, y);
}
```

Expand Down

0 comments on commit c58e8b9

Please sign in to comment.