Traits
Ek trait un methods ka set define karta hai jo ek type implement kar sakta hai — doosri languages mein interface jaisa. Ek martaba jab koi type ek trait implement kar deta hai, aap us trait ke methods ko directly usper call kar sakte hain.
trait Greet {
fn greet(&self) -> String;
}
struct Person {
name: String,
}
impl Greet for Person {
fn greet(&self) -> String {
format!("Hello, my name is {}", self.name)
}
}
fn main() {
let alice = Person { name: String::from("Alice") };
println!("{}", alice.greet());
}Hello, my name is Alice
Trait bounds
Ek generic function require kar sakta hai ke uska type parameter ek particular trait implement kare, jo T: Greet se likha jaata hai. Yeh greet_everyone ko kisi bhi aise type ka slice accept karne deta hai jo Greet implement karta ho, sirf khaas tor par Person nahi — function ek martaba likha jaata hai aur har us type ke liye kaam karta hai jo bound ko satisfy karta hai.
trait Greet {
fn greet(&self) -> String;
}
struct Person {
name: String,
}
impl Greet for Person {
fn greet(&self) -> String {
format!("Hello, my name is {}", self.name)
}
}
fn greet_everyone<T: Greet>(items: &[T]) {
for item in items {
println!("{}", item.greet());
}
}
fn main() {
let people = vec![
Person { name: String::from("Alice") },
Person { name: String::from("Bob") },
];
greet_everyone(&people);
}Hello, my name is Alice Hello, my name is Bob
Aage: generics — ek aisa function ya struct likhna jo kai types ke across kaam kare, woh general mechanism jispar trait bounds bante hain.
Practice Exercise
Ek trait Area define karein jiska method area(&self) -> f64 ho. Ise ek struct Square { side: f64 } ke liye implement karein taake area(), side * side wapas kare. side 4.0 wala ek Square banayein aur uska area() print karein.