Traits
Syntax
Trait →
unsafe? trait IDENTIFIER GenericParams? ( : Bounds? )? WhereClause?
{
InnerAttribute*
AssociatedItem*
}
A trait describes an abstract interface that types can implement. This interface consists of associated items, which come in three varieties:
The trait declaration defines a trait in the type namespace of the module or block where it is located.
Associated items are defined as members of the trait within their respective namespaces. Associated types are defined in the type namespace. Associated constants and associated functions are defined in the value namespace.
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.
Trait functions may omit the function body by replacing it with a semicolon. This indicates that the implementation must define the function. If the trait function defines a body, this definition acts as a default for any implementation which does not override it. Similarly, associated constants may omit the equal sign and expression to indicate implementations must define the constant value. Associated types must never define the type, the type may only be specified in an implementation.
#![allow(unused)]
fn main() {
// Examples of associated trait items with and without definitions.
trait Example {
const CONST_NO_DEFAULT: i32;
const CONST_WITH_DEFAULT: i32 = 99;
type TypeNoDefault;
fn method_without_default(&self);
fn method_with_default(&self) {}
}
}
Trait functions are not allowed to be const.
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)]
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);
}
}
Dyn compatibility
A dyn-compatible trait can be the base trait of a trait object. A trait is dyn compatible if it has the following qualities:
- All supertraits must also be dyn compatible.
Sizedmust not be a supertrait. In other words, it must not requireSelf: Sized.
- It must not have any associated constants.
- It must not have any associated types with generics.
- All associated functions must either be dispatchable from a trait object or be explicitly non-dispatchable:
- Dispatchable functions must:
- Not have any type parameters (although lifetime parameters are allowed).
- Be a method that does not use
Selfexcept in the type of the receiver. - Have a receiver with one of the following types:
- Not have an opaque return type; that is,
- Not be an
async fn(which has a hiddenFuturetype). - Not have a return position
impl Traittype (fn example(&self) -> impl Trait).
- Not be an
- Dispatchable functions must: