# 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.

fn main() { 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> } }

    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.