Traits - The Rust Reference

# Traits

> Syntax
> Trait :
> `unsafe`? `trait` IDENTIFIER Generics? ( `:` TypeParamBounds? )? WhereClause? `{`
> TraitItem*
> `}`

> TraitItem :
> OuterAttribute* (
> TraitFunc
> | TraitMethod
> | TraitConst
> | TraitType
> | MacroInvocationSemi
> )

> TraitFunc :
> TraitFunctionDecl ( `;` | BlockExpression )

> TraitMethod :
> TraitMethodDecl ( `;` | BlockExpression )

> TraitFunctionDecl :
> FunctionQualifiers `fn` IDENTIFIER Generics?
> `(` TraitFunctionParameters? `)`
> FunctionReturnType? WhereClause?

> TraitMethodDecl :
> FunctionQualifiers `fn` IDENTIFIER Generics?
> `(` SelfParam (`,` TraitFunctionParam)* `,`? `)`
> FunctionReturnType? WhereClause?

> TraitFunctionParameters :
> TraitFunctionParam (`,` TraitFunctionParam)* `,`?

> TraitFunctionParam† :
> OuterAttribute* ( Pattern `:` )? Type

> TraitConst :
> `const` IDENTIFIER `:` Type ( `=` Expression )? `;`

> TraitType :
> `type` IDENTIFIER ( `:` TypeParamBounds? )? `;`

A trait describes an abstract interface that types can implement. This interface consists of associated items, which come in three varieties:

- functions
- types
- constants

All traits define an implicit type parameter `Self` that refers to "the type that is implementing this interface". Traits may also contain additional type parameters. These type parameters, including `Self`, may be constrained by other traits and so forth as usual.

Traits are implemented for specific types through separate implementations.

Items associated with a trait do not need to be defined in the trait, but they may be. If the trait provides a definition, then this definition acts as a default for any implementation which does not override it. If it does not, then any implementation must provide a definition.

## Trait bounds

Generic items may use traits as bounds on their type parameters.

## Generic Traits

Type parameters can be specified for a trait to make it generic. These appear after the trait name, using the same syntax used in generic functions.

    #![allow(unused_variables)]
    fn main() {
    trait Seq<T> {
        fn len(&self) -> u32;
        fn elt_at(&self, n: u32) -> T;
        fn iter<F>(&self, f: F) where F: Fn(T);
    }
    }

## Object Safety

Object safe traits can be the base trait of a trait object. A trait is object safe if it has the following qualities (defined in RFC 255):

- It must not require `Self: Sized`
- All associated functions must either have a `where Self: Sized` bound, or
  - Not have any type parameters (although lifetime parameters are allowed), and
  - Be a method that does not use `Self` except in the type of the receiver.
- It must not have any associated constants.
- All supertraits must also be object safe.

## Supertraits

Supertraits are traits that are required to be implemented for a type to implement a specific trait. Furthermore, anywhere a generic or trait object is bounded by a trait, it has access to the associated items of its supertraits.

Supertraits are declared by trait bounds on the `Self` type of a trait and transitively the supertraits of the traits declared in those trait bounds. It is an error for a trait to be its own supertrait.

The trait with a supertrait is called a subtrait of its supertrait.

The following is an example of declaring `Shape` to be a supertrait of `Circle`.

    #![allow(unused_variables)]
    fn main() {
    trait Shape { fn area(&self) -> f64; }
    trait Circle : Shape { fn radius(&self) -> f64; }
    }

And the following is the same example, except using where clauses.

    #![allow(unused_variables)]
    fn main() {
    trait Shape { fn area(&self) -> f64; }
    trait Circle where Self: Shape { fn radius(&self) -> f64; }
    }

This next example gives `radius` a default implementation using the `area` function from `Shape`.

    #![allow(unused_variables)]
    fn main() {
    trait Shape { fn area(&self) -> f64; }
    trait Circle where Self: Shape {
        fn radius(&self) -> f64 {
            // A = pi * r^2
            // so algebraically,
            // r = sqrt(A / pi)
            (self.area() /std::f64::consts::PI).sqrt()
        }
    }
    }

This next example calls a supertrait method on a generic parameter.

    #![allow(unused_variables)]
    fn main() {
    trait Shape { fn area(&self) -> f64; }
    trait Circle : Shape { fn radius(&self) -> f64; }
    fn print_area_and_radius<C: Circle>(c: C) {
        // Here we call the area method from the supertrait `Shape` of `Circle`.
        println!("Area: {}", c.area());
        println!("Radius: {}", c.radius());
    }
    }

Similarly, here is an example of calling supertrait methods on trait objects.

    #![allow(unused_variables)]
    fn main() {
    trait Shape { fn area(&self) -> f64; }
    trait Circle : Shape { fn radius(&self) -> f64; }
    struct UnitCircle;
    impl Shape for UnitCircle { fn area(&self) -> f64 { std::f64::consts::PI } }
    impl Circle for UnitCircle { fn radius(&self) -> f64 { 1.0 } }
    let circle = UnitCircle;
    let circle = Box::new(circle) as Box<dyn Circle>;
    let nonsense = circle.radius() * circle.area();
    }

## Unsafe traits

Traits items that begin with the `unsafe` keyword indicate that implementing the trait may be unsafe. It is safe to use a correctly implemented unsafe trait. The trait implementation must also begin with the `unsafe` keyword.

`Sync` and `Send` are examples of unsafe traits.

## Parameter patterns

Function or method declarations without a body only allow IDENTIFIER or `_` wild card patterns. `mut` IDENTIFIER is currently allowed, but it is deprecated and will become a hard error in the future.

In the 2015 edition, the pattern for a trait function or method parameter is optional:

    #![allow(unused_variables)]
    fn main() {
    trait T {
        fn f(i32);  // Parameter identifiers are not required.
    }
    }

The kinds of patterns for parameters is limited to one of the following:

- IDENTIFIER
- `mut` IDENTIFIER
- `_`
- `&` IDENTIFIER
- `&&` IDENTIFIER

Beginning in the 2018 edition, function or method parameter patterns are no longer optional. Also, all irrefutable patterns are allowed as long as there is a body. Without a body, the limitations listed above are still in effect.

    #![allow(unused_variables)]
    fn main() {
    trait T {
        fn f1((a, b): (i32, i32)) {}
        fn f2(_: (i32, i32));  // Cannot use tuple pattern without a body.
    }
    }