Trait and Trait Bounds in Rust
In this article, we will understand _trait_ (feature) and _trait bounds_ (feature boundaries) in Rust through the story background of Journey to the West.
Let’s take Tang Seng and his disciples as an example to see how Rust’s traits can be used to describe their abilities and limitations.
Chapter 1: Definition and implementation of Trait
In Journey to the West, each character has unique skills.
For example, Sun Wukong can change seventy-two times, Zhu Bajie can learn water escape technique, and Sha Seng is good at using magic wands. We can abstract these skills into traits in Rust.
Sample code: Defining and implementing Trait
// Define a trait that means "flying ability"trait Fly { fn fly(&self); } // Sun Wukong realized Fly traitstruct MonkeyKing {} impl Fly for MonkeyKing { fn fly(&self) { println!("Sun Wukong rode the somersault cloud and jumped into the sky!"); } } // Zhu Bajie also realized Fly traitstruct ZhuBajie {} impl Fly for ZhuBajie { fn fly(&self) { println!("Zhu Bajie used the water escape technique and turned into a stream of clear smoke and flew away!"); } }
Code explanation
-
trait Fly
Define an interface that represents "flying ability". -
MonkeyKing
andZhuBajie
This trait is implemented separately and provides specific flight methods.
Chapter 2: Trait Bounds (feature boundaries)
During the process of obtaining scriptures, Tang Seng needed to ensure that every disciple had some ability.
For example, when crossing the Flame Mountain, he hoped that all his disciples could "put out the fire." This is equivalent to adding trait bounds to functions or structures in Rust.
Sample code: Define Trait Bounds
// Define a trait that means "the ability to extinguish fires"trait Extinguish { fn extinguish(&self); } // Sun Wukong implements Extinguish traitimpl Extinguish for MonkeyKing { fn extinguish(&self) { println!("Sun Wukong pulled out the monkey hair and turned into countless little monkeys to extinguish the flames!"); } } // Zhu Bajie also implemented Extinguish traitimpl Extinguish for ZhuBajie { fn extinguish(&self) { println!("When Zhu Bajie blew with his mouth, the flames instantly went out!"); } } // Tang Monk hopes that all his disciples can put out the fire, so he adds Trait Boundsfn cross_flame_mountain<T: Extinguish>(disciple: T) { (); } // Test codefn main() { let monkey_king = MonkeyKing {}; cross_flame_mountain(monkey_king); // Output: Sun Wukong pulls out the monkey hair and turns countless little monkeys to extinguish the flames! let zhu_bajie = ZhuBajie {}; cross_flame_mountain(zhu_bajie); // Output: Zhu Bajie blew with his mouth and the flames instantly went out!}
Code explanation
-
trait Extinguish
Defines an interface that indicates "the ability to extinguish fires". -
cross_flame_mountain
Function pass<T: Extinguish>
trait bounds are set to ensure that the passed parameters must be implementedExtinguish
trait。
Chapter 3: Blanket Implementations (blanket implementations)
In "Journey to the West", Guanyin Bodhisattva gave Tang Monk a magic weapon - the spell of tight hoop.
This magic weapon is effective for all apprentices, no matter what role they are.
This is similar to blanket implementations in Rust, which provides a default implementation for a certain type of trait.
Sample code: Blanket Implementations
trait Fly { fn fly(&self); }
Code explanation
-
impl<T: Fly> Fight for T
is a blanket implementation, which implements allFly
The type of trait is automatically providedFight
trait implementation. - This means that as long as the role is implemented
Fly
, they automatically get itFight
ability.
Chapter 4: Comprehensive Example
Let us combine the above knowledge points to build a complete "Journey to the West" scene.
// Define Traittrait Fly { fn fly(&self); } trait Extinguish { fn extinguish(&self); } // Provides default Extinguish implementation for all types that implement Flyimpl<T: Fly> Extinguish for T { fn extinguish(&self) { println!("Use the ability to extinguish the flames!"); } } // Sun Wukong realized Fly traitstruct MonkeyKing {} impl Fly for MonkeyKing { fn fly(&self) { println!("Sun Wukong rode the somersault cloud and jumped into the sky!"); } } // Zhu Bajie also realized Fly traitstruct ZhuBajie {} impl Fly for ZhuBajie { fn fly(&self) { println!("Zhu Bajie used the water escape technique and turned into a stream of clear smoke and flew away!"); } } // Tang Monk needs his disciples to have the ability to fly and extinguish firefn cross_difficulties<T: Fly + Extinguish>(disciple: T) { (); (); } // Test codefn main() { let monkey_king = MonkeyKing {}; cross_difficulties(monkey_king); // Output: // Sun Wukong rode the somersault cloud and jumped into the sky! // Use flight ability to extinguish the flames! let zhu_bajie = ZhuBajie {}; cross_difficulties(zhu_bajie); // Output: // Zhu Bajie used the water escape technique and turned into a stream of clear smoke and flew away! // Use flight ability to extinguish the flames!}
Code explanation
-
Fly
andExtinguish
are two independent traits. - Through blanket implementation, all implementations
Fly
All types are automatically obtainedExtinguish
ability. -
cross_difficulties
The function requires that the parameters passed in must be implemented at the same time.Fly
andExtinguish
。
Summarize
Through the story background of Journey to the West, we understand the core concepts of trait and trait bounds in Rust:
- Traitis an interface definition mechanism used to describe the capabilities of a role.
- Trait BoundsThe parameter types used to restrict functions or structures must implement certain traits.
- Blanket ImplementationsYou can provide a default trait implementation for all types that implement a certain type of trait.
The above is personal experience. I hope you can give you a reference and I hope you can support me more.