Coming from Ruby, polymorphism is a big part of the language. After all Ruby is a (mostly) object oriented language. Going to a language like Rust which is compiled and has an emphasis on being fast, run time polymorphism isn’t that nice as it slows down the code. This is because there’s the overhead of selecting the right implementation of a method at runtime and also because there’s no way these calls can be inlined.
This is where compile time polymorphism comes in. Many times it is clear at compile time which concrete type we’re going to use in the program. We could write it down explicitly, but it is nicer (and more flexible) if the compiler can figure it out for us.
Below is a small example of how this works.
Implementer2 are two structs that both implement the trait
TheTrait. The third struct,
Container, should be setup in such a
way that it can store any struct that implements
Setting this up correctly in Rust is a tiny bit complicated. First,
you need to let Rust know that you want to use a type variable when
Container. To do this you write
Container<T> and then use
T wherever you want to refer to this type in the struct definition.
You will notice that this never mentions the trait
place where you actually restrict this variable to the trait is in the
concrete implementation of the
Container struct. Note that the
variable I’ve used in the definition of
different from the one I’ve used in the implementation (called
Normally you wouldn’t do this as this makes the code much harder to
understand, but I wanted to show that this is “just” a variable.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
To prove that I haven’t told you any lies, let’s compile the program
and run it. You’ll clearly see that
1 2 3 4
Next time we’ll talk about how to do actual runtime polymorphism in Rust. After all it’s not always possible to know the type at compile time!