So, instead of an array of enumeration values, this time we're going to create an array of trait object references:
let mut directions = [
&Forward{ blocks: 5 },
&Turn{ slight: true, right: false },
&Forward{ blocks: 1 },
&Turn{ slight: false, right: true },
&Forward{ blocks: 2 },
&Stop{},
];
Unfortunately, if we try to compile that, we get an error, as shown here:
This time, Rust can't figure out the data type of the array just by looking at the value we're assigning to it, because that value looks like an array containing multiple data types, which is not something we can even do in Rust. The compiler is not going to go looking for traits they all implement, pick one arbitrarily, and decide that the array is actually an array of trait objects. That would be bad more often than it was helpful, so we have to tell Rust what data type the directions variable should have.
What we actually tell it is that directions is [&dyn PrintableDirection; 6]. That means that it's an array of PrintableDirection trait object references and has room for six of them. Now, the compiler knows how to correctly interpret our array expression:
let mut directions: [&dyn PrintableDirection; 6] = [
&Forward{ blocks: 5 },
&Turn{ slight: true, right: false },
&Forward{ blocks: 1 },
&Turn{ slight: false, right: true },
&Forward{ blocks: 2 },
&Stop{},
];
Now, we're ready to actually print out the driving directions:
for step in directions.iter() {
step.forward();
};
Just for fun, we'll also print out the directions for returning home:
directions.reverse();
for step in directions.iter() {
step.reverse();
};
When we compile and run all of the trait object code, we get output like this:
Yay, it works!