Trait objects

Forward, Turn, and Stop are still three different data types. There's no data type that represents Forward, Turn, Stop, and though we could create one using an enumeration, there's another way. There is a data type that represents a borrow of any data type that has the PrintableDirection trait. It's written as &dyn PrintableDirection and is called a trait object reference.

We can't just write something like let x: dyn PrintableDirection and create a variable that can store anything with the PrintableDirection trait. It needs to be a borrow, or something that stores contained data outside the stack, such as the Box type we'll look at in the next chapter.

The dyn keyword is short for dynamic dispatch, and it means that what looks and acts like a borrow in most ways is actually a little more complicated. The memory address stored in the borrow itself is actually the address of a hidden data structure.

That hidden data structure contains the actual borrow address and the memory addresses of the functions that implement the trait for the borrowed data value. When we assign a data value to a trait object, Rust initializes that hidden data structure, and when we call one of the trait functions, Rust looks up which function to actually call in the same hidden data structure.

That means that calling a function through a trait object will always have a few extra steps that the computer needs to perform, compared to calling a function on a data value with a concrete type. On the other hand, if we think about it, any mechanism that could possibly allow us to work with arbitrary data types has to allocate time and memory for keeping track of what kind of data it's working with and where the data value is stored. If we tried to create the same functionality from scratch, we'd end up doing the same thing.
..................Content has been hidden....................

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