Skip to content

Commit b24271e

Browse files
committed
TRPL: operators and overloading
I forgot these heavily use associated types, so move it after that as well.
1 parent 1114fcd commit b24271e

File tree

2 files changed

+82
-2
lines changed

2 files changed

+82
-2
lines changed

src/doc/trpl/SUMMARY.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
* [Strings](strings.md)
3838
* [Generics](generics.md)
3939
* [Traits](traits.md)
40-
* [Operators and Overloading](operators-and-overloading.md)
4140
* [Drop](drop.md)
4241
* [if let](if-let.md)
4342
* [Trait Objects](trait-objects.md)
@@ -51,6 +50,7 @@
5150
* [Casting between types](casting-between-types.md)
5251
* [Associated Types](associated-types.md)
5352
* [Unsized Types](unsized-types.md)
53+
* [Operators and Overloading](operators-and-overloading.md)
5454
* [Deref coercions](deref-coercions.md)
5555
* [Macros](macros.md)
5656
* [Raw Pointers](raw-pointers.md)
+81-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,83 @@
11
% Operators and Overloading
22

3-
Coming soon!
3+
Rust allows for a limited form of operator overloading. There are certain
4+
operators that are able to be overloaded. To support a particular operator
5+
between types, there’s a specific trait that you can implement, which then
6+
overloads the operator.
7+
8+
For example, the `+` operator can be overloaded with the `Add` trait:
9+
10+
```rust
11+
use std::ops::Add;
12+
13+
#[derive(Debug)]
14+
struct Point {
15+
x: i32,
16+
y: i32,
17+
}
18+
19+
impl Add for Point {
20+
type Output = Point;
21+
22+
fn add(self, other: Point) -> Point {
23+
Point { x: self.x + other.x, y: self.y + other.y }
24+
}
25+
}
26+
27+
fn main() {
28+
let p1 = Point { x: 1, y: 0 };
29+
let p2 = Point { x: 2, y: 3 };
30+
31+
let p3 = p1 + p2;
32+
33+
println!("{:?}", p3);
34+
}
35+
```
36+
37+
In `main`, we can use `+` on our two `Point`s, since we’ve implemented
38+
`Add<Output=Point>` for `Point`.
39+
40+
There are a number of operators that can be overloaded this way, and all of
41+
their associated traits live in the [`std::ops`][stdops] module. Check out its
42+
documentation for the full list.
43+
44+
[stdops]: ../std/ops/index.html
45+
46+
Implementing these traits follows a pattern. Let’s look at [`Add`][add] in more
47+
detail:
48+
49+
```rust
50+
# mod foo {
51+
pub trait Add<RHS = Self> {
52+
type Output;
53+
54+
fn add(self, rhs: RHS) -> Self::Output;
55+
}
56+
# }
57+
```
58+
59+
[add]: ../std/ops/trait.Add.html
60+
61+
There’s three types in total involved here: the type you `impl Add` for, `RHS`,
62+
which defaults to `Self`, and `Output`. For an expression `let z = x + y`, `x`
63+
is the `Self` type, `y` is the RHS, and `z` is the `Self::Output` type.
64+
65+
```rust
66+
# struct Point;
67+
# use std::ops::Add;
68+
impl Add<i32> for Point {
69+
type Output = f64;
70+
71+
fn add(self, rhs: i32) -> f64 {
72+
// add an i32 to a Point and get an f64
73+
# 1.0
74+
}
75+
}
76+
```
77+
78+
will let you do this:
79+
80+
```rust,ignore
81+
let p: Point = // ...
82+
let x: f64 = p + 2i32;
83+
```

0 commit comments

Comments
 (0)