Browse Source

update original

pull/677/head
funkill2 4 years ago
parent
commit
29d1e6ebe1
  1. 10
      rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/src/main.rs
  2. 37
      rustbook-en/src/ch10-01-syntax.md
  3. 13
      rustbook-en/src/ch10-02-traits.md
  4. 21
      rustbook-en/src/ch10-03-lifetime-syntax.md

10
rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/src/main.rs

@ -1,10 +1,10 @@ @@ -1,10 +1,10 @@
struct Point<T, U> {
x: T,
y: U,
struct Point<X1, Y1> {
x: X1,
y: Y1,
}
impl<T, U> Point<T, U> {
fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
impl<X1, Y1> Point<X1, Y1> {
fn mixup<X2, Y2>(self, other: Point<X2, Y2>) -> Point<X1, Y2> {
Point {
x: self.x,
y: other.y,

37
rustbook-en/src/ch10-01-syntax.md

@ -210,13 +210,20 @@ Here, we’ve defined a method named `x` on `Point<T>` that returns a reference @@ -210,13 +210,20 @@ Here, we’ve defined a method named `x` on `Point<T>` that returns a reference
to the data in the field `x`.
Note that we have to declare `T` just after `impl` so we can use it to specify
that we’re implementing methods on the type `Point<T>`. By declaring `T` as a
that we’re implementing methods on the type `Point<T>`. By declaring `T` as a
generic type after `impl`, Rust can identify that the type in the angle
brackets in `Point` is a generic type rather than a concrete type.
We could, for example, implement methods only on `Point<f32>` instances rather
than on `Point<T>` instances with any generic type. In Listing 10-10 we use the
concrete type `f32`, meaning we don’t declare any types after `impl`.
brackets in `Point` is a generic type rather than a concrete type. Because this
is declaring the generic again, we could have chosen a different name for the
generic parameter than the generic parameter declared in the struct definition,
but using the same name is conventional. Methods written within an `impl` that
declares the generic type will be defined on any instance of the type, no
matter what concrete type ends up substituting for the generic type.
The other option we have is defining methods on the type with some constraint
on the generic type. We could, for example, implement methods only on
`Point<f32>` instances rather than on `Point<T>` instances with any generic
type. In Listing 10-10 we use the concrete type `f32`, meaning we don’t declare
any types after `impl`.
<span class="filename">Filename: src/main.rs</span>
@ -234,12 +241,11 @@ point is from the point at coordinates (0.0, 0.0) and uses mathematical @@ -234,12 +241,11 @@ point is from the point at coordinates (0.0, 0.0) and uses mathematical
operations that are available only for floating point types.
Generic type parameters in a struct definition aren’t always the same as those
you use in that struct’s method signatures. For example, Listing 10-11 defines
the method `mixup` on the `Point<T, U>` struct from Listing 10-8. The method
takes another `Point` as a parameter, which might have different types from the
`self` `Point` we’re calling `mixup` on. The method creates a new `Point`
instance with the `x` value from the `self` `Point` (of type `T`) and the `y`
value from the passed-in `Point` (of type `W`).
you use in that struct’s method signatures. Listing 10-11 uses the generic
types `X1` and `Y1` for the `Point` struct and `X2` `Y2` for the `mixup` method
signature to make the example clearer. The method creates a new `Point`
instance with the `x` value from the `self` `Point` (of type `X1`) and the `y`
value from the passed-in `Point` (of type `Y2`).
<span class="filename">Filename: src/main.rs</span>
@ -260,9 +266,10 @@ call will print `p3.x = 5, p3.y = c`. @@ -260,9 +266,10 @@ call will print `p3.x = 5, p3.y = c`.
The purpose of this example is to demonstrate a situation in which some generic
parameters are declared with `impl` and some are declared with the method
definition. Here, the generic parameters `T` and `U` are declared after `impl`,
because they go with the struct definition. The generic parameters `V` and `W`
are declared after `fn mixup`, because they’re only relevant to the method.
definition. Here, the generic parameters `X1` and `Y1` are declared after
`impl` because they go with the struct definition. The generic parameters `X2`
and `Y2` are declared after `fn mixup`, because they’re only relevant to the
method.
### Performance of Code Using Generics

13
rustbook-en/src/ch10-02-traits.md

@ -79,7 +79,8 @@ the specific behavior that we want the methods of the trait to have for the @@ -79,7 +79,8 @@ the specific behavior that we want the methods of the trait to have for the
particular type.
After implementing the trait, we can call the methods on instances of
`NewsArticle` and `Tweet` in the same way we call regular methods, like this:
`NewsArticle` and `Tweet` in the same way we call regular methods. Here's an
example of how a binary crate could use our library crate:
```rust,ignore
{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/main.rs:here}}
@ -100,12 +101,12 @@ another crate to implement it, which it is because we put the `pub` keyword @@ -100,12 +101,12 @@ another crate to implement it, which it is because we put the `pub` keyword
before `trait` in Listing 10-12.
One restriction to note with trait implementations is that we can implement a
trait on a type only if either the trait or the type is local to our crate.
For example, we can implement standard library traits like `Display` on a
custom type like `Tweet` as part of our `aggregator` crate functionality,
trait on a type only if at least one of the trait or the type is local to our
crate. For example, we can implement standard library traits like `Display` on
a custom type like `Tweet` as part of our `aggregator` crate functionality,
because the type `Tweet` is local to our `aggregator` crate. We can also
implement `Summary` on `Vec<T>` in our `aggregator` crate, because the
trait `Summary` is local to our `aggregator` crate.
implement `Summary` on `Vec<T>` in our `aggregator` crate, because the trait
`Summary` is local to our `aggregator` crate.
But we can’t implement external traits on external types. For example, we can’t
implement the `Display` trait on `Vec<T>` within our `aggregator` crate,

21
rustbook-en/src/ch10-03-lifetime-syntax.md

@ -193,10 +193,11 @@ lifetime. @@ -193,10 +193,11 @@ lifetime.
Now let’s examine lifetime annotations in the context of the `longest`
function. As with generic type parameters, we need to declare generic lifetime
parameters inside angle brackets between the function name and the parameter
list. The constraint we want to express in this signature is that all the
references in the parameters and the return value must have the same lifetime.
We’ll name the lifetime `'a` and then add it to each reference, as shown in
Listing 10-22.
list. The constraint we want to express in this signature is that the lifetimes
of both of the parameters and the lifetime of the returned reference are
related such that the returned reference will be valid as long as both the
parameters are. We’ll name the lifetime `'a` and then add it to each reference,
as shown in Listing 10-22.
<span class="filename">Filename: src/main.rs</span>
@ -217,7 +218,9 @@ long as lifetime `'a`. The function signature also tells Rust that the string @@ -217,7 +218,9 @@ long as lifetime `'a`. The function signature also tells Rust that the string
slice returned from the function will live at least as long as lifetime `'a`.
In practice, it means that the lifetime of the reference returned by the
`longest` function is the same as the smaller of the lifetimes of the
references passed in. These constraints are what we want Rust to enforce.
references passed in. These relationships are what we want Rust to use when
analyzing this code.
Remember, when we specify the lifetime parameters in this function signature,
we’re not changing the lifetimes of any values passed in or returned. Rather,
we’re specifying that the borrow checker should reject any values that don’t
@ -588,10 +591,10 @@ This is the `longest` function from Listing 10-22 that returns the longer of @@ -588,10 +591,10 @@ This is the `longest` function from Listing 10-22 that returns the longer of
two string slices. But now it has an extra parameter named `ann` of the generic
type `T`, which can be filled in by any type that implements the `Display`
trait as specified by the `where` clause. This extra parameter will be printed
before the function compares the lengths of the string slices, which is why the
`Display` trait bound is necessary. Because lifetimes are a type of generic,
the declarations of the lifetime parameter `'a` and the generic type parameter
`T` go in the same list inside the angle brackets after the function name.
using `{}`, which is why the `Display` trait bound is necessary. Because
lifetimes are a type of generic, the declarations of the lifetime parameter
`'a` and the generic type parameter `T` go in the same list inside the angle
brackets after the function name.
## Summary

Loading…
Cancel
Save