Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Traits can be used as types of function arguments, using the impl keyword. This keyword means that the concrete type will be decided at compile time. Since multiple concrete types can be used with this function as long as they implement the required trait, the compiler will generate a function for each concrete type used:

Using the generic notation, we can express the fact that f1 and f2 must have the same concrete type that implements the Media trait:

We need a Movie structure to test our trait:

With the trait implementation:

We define two movies:

The two functions are tested using the two movies:

Movie "Despicable Me 2" lasts 98 minutes.
Movie "Despicable Me 2" lasts longer than movie "Despicable Me".

32.3.1Multiple traits

It is possible to have multiple trait bounds on the same argument, using the + sign to link them.

Let us first define another trait for playing a video:

We implement this new trait for the Movie structure:

We define now a function to play a video that takes an item that implements the two traits Media and Video:

This function could also be defined directly as a generic:

Here is the invocation of the function with a movie instance:

Video: Despicable Me, length: 95 min
Playing video Despicable Me...

32.3.2Returning a trait

Returning a trait is also possible. Here is the impl syntax with two traits bound:

Movie "Despicable Me 3" lasts 90 minutes.
()

For instance, we define a trait to build an object from a title and a duration:

Then we implement it for Movie:

We now add the FromTitle as a bound and use its constructor method:

To use it we need now to specify the wanted type (here Movie):

Movie "Despicable Me 3" lasts 90 minutes.

32.3.3Where clause

The where clause allows for clearer declarations. For instance, in the following function we want to merge two different video files, with possibly different types. We express the trait bounds inside the where clause, making the function header clearer:

Here is the execution:

Merging "Despicable Me" with "Despicable Me 2".
Movie "Merged movies" lasts 193 minutes.

32.3.4Bounding a generic method

Trait bounds can also be used to specialize partially a generic type, and implement methods only for this specialization.

For instance given the following generic structure:

We may define the following method that will exist only for primitive integers. This example requires the external num_traits crate, which is not available in this notebook’s kernel, so it is shown but not executed:

If we define the following bag of integers:

Couldn't automatically determine type of variable `bag`.
Please give it an explicit type.

We would then be able to call the sum() method: