AnyCompiler

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());
}
Output
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);
}
Output
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.