- The above example shows that you can print your own display for a structure using Display trait from std::fmt.
- You can take trait as a parameter like below:
struct Person{
first_name: String,
last_name: String,
age: i32
}
trait FullFunction {
fn full_name(&self) -> String;
}
fn print_full_name_and_age(value: &impl HasFunction){
println!("{}", value.full_name())
}
fn main(){
let person: Person = Person::new(full_name:"Sanu Shilshad");
print_full_name_and_age(&person);
}
- The trait parameter says that it takes any struct that has HasFunction implementation.
- You can write the above code much better like below:
struct Person{
first_name: String,
last_name: String,
age: i32
}
trait FullFunction {
fn full_name(&self) -> String;
}
fn print_details<T: HasFunction>(value: &T){
println!("{}", value.full_name())
}
fn main(){
let person: Person = Person::new(full_name:"Sanu Shilshad");
print_full_name_and_age(&person);
}
- The above method is called Trait Bound Box.
- You can add multiple traits like below
struct Person{
first_name: String,
last_name: String,
age: i32
}
trait FullFunction {
fn full_name(&self) -> String;
}
trait CanRun{
fn run(&self);
}
impl CanRun for Person{
fn run(&self){
todo!()
}
}
fn print_details<T: HasFunction + CanRun>(value: &T){
println!("{}", value.full_name());
value.run();
}
fn main(){
let person: Person = Person::new(full_name:"Sanu Shilshad");
}
- You can also rewrite the above code block like below:
struct Person{
first_name: String,
last_name: String,
age: i32
}
trait FullFunction {
fn full_name(&self) -> String;
}
trait CanRun{
fn run(&self);
}
impl CanRun for Person{
fn run(&self){
todo!()
}
}
fn print_details<T>(value: &T)
where
T: HasFullName + CanRun,
{
println!("{}", value.full_name());
value,run();
}
fn main(){
let person: Person = Person::new(full_name:"Sanu Shilshad");
print_full_name_and_age(&person);
}
- Traits can be implemented on other traits like below:
trait HasName {
fn first_name(&self) -> &str;
fn last_name(&self) -> &str;
}
trait HasFullName
where
Self: HasName,
{
fn full_name(&self) -> &str;
}
impl<T> HasFullName for T
where
T:HasName,
{
fn full_name(&self) -> String {
format!("{} {}", self.first_name(), self.last_name())
}
}
- This is called a binding a trait to another.
- In the above example HasFullName is created as long as object has a HasName trait.
- And the implemention of full_name method in HasFullName can be shown as above.
trait HasName {
fn first_name(&self) -> &str;
fn last_name(&self) -> &str;
}
trait HasFullName
where
Self: HasName,
{
fn full_name(&self) -> &str;
}
impl<T> HasFullName for T
where
T:HasName,
{
fn full_name(&self) -> String {
format!("{} {}", self.first_name(), self.last_name())
}
}
impl HasName for Person{
fn first_name(&self) -> &str {
&self.first_name
}
fn last_name(&self) -> &str {
&self.last_name
}
}
fn main(){
let person: Person = Person::new(full_name:"Sanu Shilshad");
let full_name: String = person.full_name();
println!("{}", full_name)l
}
Comments
Post a Comment