summary refs log tree commit diff
path: root/src/doc/style/features/traits/objects.md
blob: 38494a9b9bc3c02a0b7f529849c1584990e5bb23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
% Using trait objects

> **[FIXME]** What are uses of trait objects other than heterogeneous collections?

Trait objects are useful primarily when _heterogeneous_ collections of objects
need to be treated uniformly; it is the closest that Rust comes to
object-oriented programming.

```rust
struct Frame  { ... }
struct Button { ... }
struct Label  { ... }

trait Widget  { ... }

impl Widget for Frame  { ... }
impl Widget for Button { ... }
impl Widget for Label  { ... }

impl Frame {
    fn new(contents: &[Box<Widget>]) -> Frame {
        ...
    }
}

fn make_gui() -> Box<Widget> {
    let b: Box<Widget> = box Button::new(...);
    let l: Box<Widget> = box Label::new(...);

    box Frame::new([b, l]) as Box<Widget>
}
```

By using trait objects, we can set up a GUI framework with a `Frame` widget that
contains a heterogeneous collection of children widgets.

**Pros**:

* _Heterogeneity_. When you need it, you really need it.
* _Code size_. Unlike generics, trait objects do not generate specialized
  (monomorphized) versions of code, which can greatly reduce code size.

**Cons**:

* _No generic methods_. Trait objects cannot currently provide generic methods.
* _Dynamic dispatch and fat pointers_. Trait objects inherently involve
  indirection and vtable dispatch, which can carry a performance penalty.
* _No Self_. Except for the method receiver argument, methods on trait objects
  cannot use the `Self` type.