diff --git a/src/doc/trpl/generics.md b/src/doc/trpl/generics.md index c28d7c71608b..a8fdec805de6 100644 --- a/src/doc/trpl/generics.md +++ b/src/doc/trpl/generics.md @@ -101,11 +101,6 @@ fn takes_two_things(x: T, y: U) { } ``` -Generic functions are most useful with ‘trait bounds’, which we’ll cover in the -[section on traits][traits]. - -[traits]: traits.html - ## Generic structs You can store a generic type in a `struct` as well: @@ -122,3 +117,28 @@ let float_origin = Point { x: 0.0, y: 0.0 }; Similarly to functions, the `` is where we declare the generic parameters, and we then use `x: T` in the type declaration, too. + +When you want to add an implementation for the generic struct, you just +declare the type parameter after the `impl`: + +```rust +# struct Point { +# x: T, +# y: T, +# } +# +impl Point { + fn swap(&mut self) { + std::mem::swap(&mut self.x, &mut self.y); + } +} +``` + +So far you’ve seen generics that take absolutely any type. These are useful in +many cases: you’ve already seen `Option`, and later you’ll meet universal +container types like [`Vec`][Vec]. On the other hand, often you want to +trade that flexibility for increased expressive power. Read about [trait +bounds][traits] to see why and how. + +[traits]: traits.html +[Vec]: ../std/vec/struct.Vec.html diff --git a/src/doc/trpl/traits.md b/src/doc/trpl/traits.md index 687e2bbf00e7..e7542756d52e 100644 --- a/src/doc/trpl/traits.md +++ b/src/doc/trpl/traits.md @@ -152,6 +152,57 @@ We get a compile-time error: 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 +type `Rectangle` and its operation `is_square()`: + +```rust +struct Rectangle { + x: T, + y: T, + width: T, + height: T, +} + +impl Rectangle { + fn is_square(&self) -> bool { + self.width == self.height + } +} + +fn main() { + let mut r = Rectangle { + x: 0, + y: 0, + width: 47, + height: 47, + }; + + assert!(r.is_square()); + + r.height = 42; + assert!(!r.is_square()); +} +``` + +`is_square()` needs to check that the sides are equal, so the sides must be of +a type that implements the [`core::cmp::PartialEq`][PartialEq] trait: + +```ignore +impl Rectangle { ... } +``` + +Now, a rectangle can be defined in terms of any type that can be compared for +equality. + +[PartialEq]: ../core/cmp/trait.PartialEq.html + + + +# Rules for implementing traits + So far, we’ve only added trait implementations to structs, but you can implement a trait for any type. So technically, we _could_ implement `HasArea` for `i32`: