Follow Blog via Email

Rust: Traits

Rust 0.12

Traits in Rust are similar to interfaces in a language like C#. The definition of a trait is that they are a collection of concrete methods that are used to extend an existing class using a name resolution policy to prevent multiple inheritance conflicts.

In Rust, traits are divided into a trait block which defines methods and an implementation block for each type which implements the trait. You can see the combination of these two components as the trait. This division allows us to implement methods at two level; at the general trait level and at the type level. When defining a default definition at the trait level it is not necessary to explicitly implement said method at the type level unless we wish to override the default with a type specific implementation.

Unimplemented method definitions must be implemented by a type which implements the trait or this will raise a compile time error.

Non-surprisingly, the Rust compiler gives out an error. The way to call the proper method isn’t so clear though. There is a proposed syntax that would allow to define the correct method to call but it hasn’t been implemented in the language as of this writing (remember Rust is pre-1.0).

In the meantime, one way to do it would be to have a function which receives a generic type which is constrained to the trait we want and call the method from this constrained generic parameter.

Returning a trait

Having a function return a trait is not something that is as easy as I would have expected. You can’t simply define a function as such:

fn return_trait(&counter: Counter) -> Logger {
// doesn't work
}

To do this we need some other concepts which I will cover in another post.
For now we still have a basic idea of how to use traits.