Implement Only and Exactly The Needed Methods
This post covers the practice of using functions to return struct instances that have implemented a specific trait that is needed in that context.
First; Separate the entity from the methods it needs
Imagine a metal box moving around on a conveyor belt. It’s zipping around the belt system until it gets diverted into a station where some robotic arms get attached to it.
It moves the arms, testing them and verifying the procedure worked. Then it uses its arms to reach up to grab a handle that is attached to the bottom of another convert system, to move itself to another station.
At the next station, its arms get removed by the station tooling, and a camera gets attached. It starts recording some video data into itself as it rides around on the conveyor belts.
This imagery could continue on forever, but the idea remains that the package is one thing, and its ‘implements’ are another.
This concept is how we will be imaging our structs and traits, where the box is our struct, and the traits are our robot arms and cameras.
A freshly initialized struct with trait implementation
There are plenty of scenarios where this is relevant, messages, short-life-cycle sprites, etc. I’m just going to create a bland Person struct and show how Traits can be used to interact with the Person struct.
Let’s use an example program flow:
Create + Implement Function Pattern
Create the new Person struct
Implement a trait that is relevant for that struct in two different scenarios
The two traits will make it possible to interact with two different areas of the struct
The struct can now use only the tooling it needs, whenever it’s relevant to do so
So the new instance we create will exist long enough to be populated and then published via a function out of this context, where the borrow-checker can then clean up its used memory. Cool!
Example Code:
Example Code Unit Tests:
Existing Struct Instances; Gear Up!
I was able to create a pattern I can conditionally invoke a function that implements a desired trait for creating clones of existing objects. I’m imagining something crazy like in a video game where an enemy character is capable of creating duplicates of themselves and you have to defeat them.
This feels close to factories or even abstract factories depending on the application.
More Example Code:
Testing:
Conclusion
Creating new instances of structs when you need them is cool. Creating new instances of structs that have only exactly the methods you want when you need them is even cooler.
Angering the data is not cool. Don’t do that.
I’m still learning a lot, so I don’t feel that this post adequately covers the inspiration I’m getting right now. I’m very impressed with Traits and after this kind of week-long foray poking and prodding the compiler to see what I can do, I admit that I’m really starting to enjoy coding in Rust.
The discovery that I need to work with the compiler was a huge one. I began to want to ‘think how it thinks’, vs. trying to program how I have been for the past 10 years. It’s doing exactly what I wanted, which is broadening the abstract ideas I have about programming, architecture, and patterns.