Copyedit generics.md and traits.md
Squashed at reviewer's request: Add heading at the end of the introductory material Spice up introductory paragraphs a bit Use quotes instead of <code> for phrase Remove "other" in "other restrictions" (it's not obvious that any other restrictions have been mentioned) "Default methods" is a second-level heading, but is not a subsection of "Where clause" Reword "Default methods" introduction: it's not the "last feature" on this page
This commit is contained in:
parent
556b0815d7
commit
427736931b
@ -6,7 +6,7 @@ Generics are called ‘parametric polymorphism’ in type theory,
|
||||
which means that they are types or functions that have multiple forms (‘poly’
|
||||
is multiple, ‘morph’ is form) over a given parameter (‘parametric’).
|
||||
|
||||
Anyway, enough with type theory, let’s check out some generic code. Rust’s
|
||||
Anyway, enough type theory, let’s check out some generic code. Rust’s
|
||||
standard library provides a type, `Option<T>`, that’s generic:
|
||||
|
||||
```rust
|
||||
@ -27,7 +27,7 @@ let x: Option<i32> = Some(5);
|
||||
|
||||
In the type declaration, we say `Option<i32>`. Note how similar this looks to
|
||||
`Option<T>`. So, in this particular `Option`, `T` has the value of `i32`. On
|
||||
the right-hand side of the binding, we do make a `Some(T)`, where `T` is `5`.
|
||||
the right-hand side of the binding, we make a `Some(T)`, where `T` is `5`.
|
||||
Since that’s an `i32`, the two sides match, and Rust is happy. If they didn’t
|
||||
match, we’d get an error:
|
||||
|
||||
|
@ -47,8 +47,11 @@ As you can see, the `trait` block looks very similar to the `impl` block,
|
||||
but we don’t define a body, just a type signature. When we `impl` a trait,
|
||||
we use `impl Trait for Item`, rather than just `impl Item`.
|
||||
|
||||
We can use traits to constrain our generics. Consider this function, which
|
||||
does not compile:
|
||||
## Traits bounds for generic functions
|
||||
|
||||
Traits are useful because they allow a type to make certain promises about its
|
||||
behavior. Generic functions can exploit this to constrain the types they
|
||||
accept. Consider this function, which does not compile:
|
||||
|
||||
```rust,ignore
|
||||
fn print_area<T>(shape: T) {
|
||||
@ -75,7 +78,7 @@ fn print_area<T: HasArea>(shape: T) {
|
||||
}
|
||||
```
|
||||
|
||||
The syntax `<T: HasArea>` means `any type that implements the HasArea trait`.
|
||||
The syntax `<T: HasArea>` means “any type that implements the `HasArea` trait.”
|
||||
Because traits define function type signatures, we can be sure that any type
|
||||
which implements `HasArea` will have an `.area()` method.
|
||||
|
||||
@ -154,8 +157,8 @@ error: the trait `HasArea` is not implemented for the type `_` [E0277]
|
||||
|
||||
## Traits bounds for generic structs
|
||||
|
||||
Trait constraints also can apply to implementations for generic structs. Just
|
||||
append the constraint when you declare type parameters. Here is a new type
|
||||
Your generic structs can also benefit from trait constraints. All you need to
|
||||
do is append the constraint when you declare type parameters. Here is a new
|
||||
type `Rectangle<T>` and its operation `is_square()`:
|
||||
|
||||
```rust
|
||||
@ -232,7 +235,7 @@ impl HasArea for i32 {
|
||||
It is considered poor style to implement methods on such primitive types, even
|
||||
though it is possible.
|
||||
|
||||
This may seem like the Wild West, but there are two other restrictions around
|
||||
This may seem like the Wild West, but there are two restrictions around
|
||||
implementing traits that prevent this from getting out of hand. The first is
|
||||
that if the trait isn’t defined in your scope, it doesn’t apply. Here’s an
|
||||
example: the standard library provides a [`Write`][write] trait which adds
|
||||
@ -397,10 +400,10 @@ This shows off the additional feature of `where` clauses: they allow bounds
|
||||
where the left-hand side is an arbitrary type (`i32` in this case), not just a
|
||||
plain type parameter (like `T`).
|
||||
|
||||
## Default methods
|
||||
# Default methods
|
||||
|
||||
There’s one last feature of traits we should cover: default methods. It’s
|
||||
easiest just to show an example:
|
||||
If you already know how a typical implementor will define a method, you can
|
||||
let your trait supply a default:
|
||||
|
||||
```rust
|
||||
trait Foo {
|
||||
|
Loading…
x
Reference in New Issue
Block a user