Traits

A trait is a name and formal definition for a specific bit of functionality that a data type may provide. Previously, we've talked about how data types might have the Copy trait, and how, when they do, the compiler copies them instead of moving them. That is the general idea: when a trait is implemented for a data type, that data type gains the ability to interact with the rest of the program in some specific way.

Some of the built-in traits, such as Copy, actually affect how the compiler interacts with the type, but we're more interested in creating our own traits here. We'll talk about those built-in traits in a later chapter.

That's all very abstract, so let's get more concrete by looking at the same "driving directions" problem that we previously solved with an enumeration. We still want to be able to have an array of driving instructions, and print them out in order, so let's create a trait that represents the ability to print out a driving instruction:

pub trait PrintableDirection {
fn forward(&self);
fn reverse(&self);
}

The trait keyword introduces a trait, unsurprisingly. Inside of it, we have the signatures of the functions that make up the interface of this trait. In other words, if a data type is going to have the PrintableDirection trait, it needs to provide implementations of these functions that are specialized for that type and trait.

It's possible for one data type to have multiple implemented functions with the same name, as long as each of those functions is part of a different trait. Traits don't need to worry about name collisions with other traits or the basic data type.

We've expanded the functionality beyond what we did with enumerations, by specifying that a data value that has the PrintableDirection trait knows how to print itself out in both the going to and coming from directions of travel—or, at least, that's what we intend for the forward and reverse functions to mean.

Traits can specify functions by just providing a signature, as before, or they can also provide a default implementation of the function, by simply filling in a complete function definition instead. When the trait is implemented for a particular data type, functions with default implementations do not have to be implemented, though they can be, if necessary.

Notice that the function signatures inside the trait do not have the pub keyword. The trait itself is public or not, as a whole. In this case (and most cases), the trait is public, so the functions that it requires are automatically public.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.71.211