Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge pull request rust-lang#1951 from mlevesquedion/fix/duck-typing-… #1

Merged
merged 8 commits into from
Oct 14, 2019
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