From b24271ee9d224d8636a722a9efcef7b8e20f4464 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Thu, 23 Apr 2015 12:16:45 -0400 Subject: [PATCH] TRPL: operators and overloading I forgot these heavily use associated types, so move it after that as well. --- src/doc/trpl/SUMMARY.md | 2 +- src/doc/trpl/operators-and-overloading.md | 82 ++++++++++++++++++++++- 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/doc/trpl/SUMMARY.md b/src/doc/trpl/SUMMARY.md index 0edadeb628e80..272f53eff1fbc 100644 --- a/src/doc/trpl/SUMMARY.md +++ b/src/doc/trpl/SUMMARY.md @@ -37,7 +37,6 @@ * [Strings](strings.md) * [Generics](generics.md) * [Traits](traits.md) - * [Operators and Overloading](operators-and-overloading.md) * [Drop](drop.md) * [if let](if-let.md) * [Trait Objects](trait-objects.md) @@ -51,6 +50,7 @@ * [Casting between types](casting-between-types.md) * [Associated Types](associated-types.md) * [Unsized Types](unsized-types.md) + * [Operators and Overloading](operators-and-overloading.md) * [Deref coercions](deref-coercions.md) * [Macros](macros.md) * [Raw Pointers](raw-pointers.md) diff --git a/src/doc/trpl/operators-and-overloading.md b/src/doc/trpl/operators-and-overloading.md index f6f9d5cae1921..6a594659c37d2 100644 --- a/src/doc/trpl/operators-and-overloading.md +++ b/src/doc/trpl/operators-and-overloading.md @@ -1,3 +1,83 @@ % Operators and Overloading -Coming soon! +Rust allows for a limited form of operator overloading. There are certain +operators that are able to be overloaded. To support a particular operator +between types, there’s a specific trait that you can implement, which then +overloads the operator. + +For example, the `+` operator can be overloaded with the `Add` trait: + +```rust +use std::ops::Add; + +#[derive(Debug)] +struct Point { + x: i32, + y: i32, +} + +impl Add for Point { + type Output = Point; + + fn add(self, other: Point) -> Point { + Point { x: self.x + other.x, y: self.y + other.y } + } +} + +fn main() { + let p1 = Point { x: 1, y: 0 }; + let p2 = Point { x: 2, y: 3 }; + + let p3 = p1 + p2; + + println!("{:?}", p3); +} +``` + +In `main`, we can use `+` on our two `Point`s, since we’ve implemented +`Add` for `Point`. + +There are a number of operators that can be overloaded this way, and all of +their associated traits live in the [`std::ops`][stdops] module. Check out its +documentation for the full list. + +[stdops]: ../std/ops/index.html + +Implementing these traits follows a pattern. Let’s look at [`Add`][add] in more +detail: + +```rust +# mod foo { +pub trait Add { + type Output; + + fn add(self, rhs: RHS) -> Self::Output; +} +# } +``` + +[add]: ../std/ops/trait.Add.html + +There’s three types in total involved here: the type you `impl Add` for, `RHS`, +which defaults to `Self`, and `Output`. For an expression `let z = x + y`, `x` +is the `Self` type, `y` is the RHS, and `z` is the `Self::Output` type. + +```rust +# struct Point; +# use std::ops::Add; +impl Add for Point { + type Output = f64; + + fn add(self, rhs: i32) -> f64 { + // add an i32 to a Point and get an f64 +# 1.0 + } +} +``` + +will let you do this: + +```rust,ignore +let p: Point = // ... +let x: f64 = p + 2i32; +```