diff options
| author | Leif Arne Storset <leifarne@storset.net> | 2015-07-19 16:23:40 +0200 |
|---|---|---|
| committer | Leif Arne Storset <leifarne@storset.net> | 2015-07-30 21:49:13 +0200 |
| commit | 556b0815d779a50a151c44032febf3ce253e621e (patch) | |
| tree | 0f88ea62fb6a2ae0def84e4ac721841ab6dad2b1 | |
| parent | 0e92165eafee26e0fb27f9a3756e8a68884d685d (diff) | |
| download | rust-556b0815d779a50a151c44032febf3ce253e621e.tar.gz rust-556b0815d779a50a151c44032febf3ce253e621e.zip | |
Using operator traits in generic structs
| -rw-r--r-- | src/doc/trpl/operators-and-overloading.md | 52 | ||||
| -rw-r--r-- | src/doc/trpl/traits.md | 6 |
2 files changed, 58 insertions, 0 deletions
diff --git a/src/doc/trpl/operators-and-overloading.md b/src/doc/trpl/operators-and-overloading.md index 6a594659c37..e53664eeb55 100644 --- a/src/doc/trpl/operators-and-overloading.md +++ b/src/doc/trpl/operators-and-overloading.md @@ -81,3 +81,55 @@ will let you do this: let p: Point = // ... let x: f64 = p + 2i32; ``` + +# Using operator traits in generic structs + +Now that we know how operator traits are defined, we can define our `HasArea` +trait and `Square` struct from the [traits chapter][traits] more generically: + +[traits]: traits.html + +```rust +use std::ops::Mul; + +trait HasArea<T> { + fn area(&self) -> T; +} + +struct Square<T> { + x: T, + y: T, + side: T, +} + +impl<T> HasArea<T> for Square<T> + where T: Mul<Output=T> + Copy { + fn area(&self) -> T { + self.side * self.side + } +} + +fn main() { + let s = Square { + x: 0.0f64, + y: 0.0f64, + side: 12.0f64, + }; + + println!("Area of s: {}", s.area()); +} +``` + +For `HasArea` and `Square`, we just declare a type parameter `T` and replace +`f64` with it. The `impl` needs more involved modifications: + +```ignore +impl<T> HasArea<T> for Square<T> + where T: Mul<Output=T> + Copy { ... } +``` + +The `area` method requires that we can multiply the sides, so we declare that +type `T` must implement `std::ops::Mul`. Like `Add`, mentioned above, `Mul` +itself takes an `Output` parameter: since we know that numbers don't change +type when multiplied, we also set it to `T`. `T` must also support copying, so +Rust doesn't try to move `self.side` into the return value. diff --git a/src/doc/trpl/traits.md b/src/doc/trpl/traits.md index e7542756d52..0f2efd4657b 100644 --- a/src/doc/trpl/traits.md +++ b/src/doc/trpl/traits.md @@ -199,7 +199,13 @@ equality. [PartialEq]: ../core/cmp/trait.PartialEq.html +Here we defined a new struct `Rectangle` that accepts numbers of any +precision—really, objects of pretty much any type—as long as they can be +compared for equality. Could we do the same for our `HasArea` structs, `Square` +and `Circle`? Yes, but they need multiplication, and to work with that we need +to know more about [operator traits][operators-and-overloading]. +[operators-and-overloading]: operators-and-overloading.html # Rules for implementing traits |
