about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeif Arne Storset <leifarne@storset.net>2015-07-19 16:23:40 +0200
committerLeif Arne Storset <leifarne@storset.net>2015-07-30 21:49:13 +0200
commit556b0815d779a50a151c44032febf3ce253e621e (patch)
tree0f88ea62fb6a2ae0def84e4ac721841ab6dad2b1
parent0e92165eafee26e0fb27f9a3756e8a68884d685d (diff)
downloadrust-556b0815d779a50a151c44032febf3ce253e621e.tar.gz
rust-556b0815d779a50a151c44032febf3ce253e621e.zip
Using operator traits in generic structs
-rw-r--r--src/doc/trpl/operators-and-overloading.md52
-rw-r--r--src/doc/trpl/traits.md6
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