Impl Block

From Rust Community Wiki

Not to be confused with Impl Trait

impl blocks declare type-associated items.

Inherent impl[edit]

An impl block may be simply associated with a type. This is called an "inherent impl", and has the syntax impl Type { /* contents */ }.

An inherent impl must be declared in the same crate as the type itself.

Trait impl[edit]

See also Traits.

A trait impl declares all associated items that are required by the trait definition, and look like impl Trait for Type { /* contents */ }. Trait impls are subject to the Orphan Rules.

Associated Items[edit]

Associated Functions[edit]

Associated functions are the foundation of "object oriented programming" in Rust. They provide a standard, easy-to-understand way to associate data types with functions that operate on them.

An associated function may or may not accept a self parameter. If it does, that function is usually called a "method." Methods support method call syntax, which eliminates the need to explicitly specify the type name that the method is associated with, using SELF.METHOD() syntax:

struct DataType;

impl DataType {
    fn method(self) {
        println!("DataType::method");
    }
}

enum MessageType {
    Data(DataType),
    None,
}

impl MessageType {
    fn method(self) {
        println!("MessageType::method");
    }
}

fn main() {
    let d = DataType;
    d.method();
    let m = MessageType::None;
    m.method();
    let d2 = DataType;
    DataType::method(d2);
    let m2 = MessageType::Data(DataType);
    MessageType::method(m2);
}


DataType::Method
MessageType::None
DataType::Method
MessageType::None

The first two method calls, d.method() and m.method(), were statically dispatched to the corresponding impl blocks and functions based on the type of the receiver.

If the type seems ambiguous, then it can still be specified by hand. This is known as fully-qualified function call syntax.

Associated Types and Constants[edit]

Other associated items have no support for the self parameter, and typically need to be explicitly named on the type, just like if they had been declared directly inside a module.

Additionally, associated types must be type aliases. This, for example, is not allowed:

struct DataType;

impl DataType {
    struct DataType2 {
        n: u32,
    }
}

error: struct is not supported in `trait`s or `impl`s