Skip to content

Commit f8485e9

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 f8485e9

File tree

2 files changed

+84
-2
lines changed

2 files changed

+84
-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)
+83-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,85 @@
11
% Operators and Overloading
22

3-
Coming soon!
3+
Rust does not have general support for overloading operators or creating new
4+
operators. However, there are certain operators in Rust that _are_ able to
5+
be overloaded. To support a particular operator between types, there’s a
6+
specific trait that you can implement, which then 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+
All of these traits follow a similar pattern. Let’s look at [`Add`][] in more detail:
41+
42+
```rust
43+
# mod foo {
44+
pub trait Add<RHS = Self> {
45+
type Output;
46+
47+
fn add(self, rhs: RHS) -> Self::Output;
48+
}
49+
# }
50+
```
51+
52+
[add]: ../std/ops/trait.Add.html
53+
54+
There’s three types in total involved here: the type you `impl Add` for, and
55+
two [associated types][at]: `RHS`, which defaults to `Self`, and `Output`. They
56+
correspond to the three parts of `x + y = z`: the type you `impl` for is `x`,
57+
`RHS` is `y`, and `Output` is `z`. So this:
58+
59+
```rust
60+
# struct Point;
61+
# use std::ops::Add;
62+
impl Add<i32> for Point {
63+
type Output = f64;
64+
65+
fn add(self, rhs: i32) -> f64 {
66+
// add an i32 to a Point and get an f64
67+
# 1.0
68+
}
69+
}
70+
```
71+
72+
[at]: associated-types.html
73+
74+
will let you do this:
75+
76+
```rust,ignore
77+
let p: Point = // ...
78+
let x: f64 = p + 2i32;
79+
```
80+
81+
There are a number of operators that can be overloaded this way, and all of
82+
their associated traits live in the [`std::ops`][stdops] module. Check out its
83+
documentation for the details.
84+
85+
[stdops]: ../std/ops/index.html

0 commit comments

Comments
 (0)