← Back to Rust Course | Chapter 14: Closures, Iterators & Async | Lesson 1 of 6

Closure Traits: Fn, FnMut और FnOnce

Closures के तीन flavors हैं इस आधार पर कि वे सिर्फ उन चीज़ों को देखते हैं, बदलते हैं, या उपयोग करके खत्म कर देते हैं जो उन्होंने capture की हैं।
Syntax
rust
fn name<F: Fn(Param) -> Ret>(f: F) {}      // borrows
fn name<F: FnMut(Param) -> Ret>(mut f: F) {} // mutates
fn name<F: FnOnce() -> Ret>(f: F) {}        // consumes

Fn: Read-Only Captures

एक closure जो सिर्फ captured variables पढ़ता है Fn implement करता है, और बिना किसी restriction के कई बार call किया जा सकता है।

उदाहरण: Fn: Read-Only Captures

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `greeting`, set to `String::from("Hello")`
    let greeting = String::from("Hello");
    // Declare an immutable variable `greet`, set to `|| println!("{}, world!", greeting)`
    let greet = || println!("{}, world!", greeting);
    greet();
    greet();
}

FnMut: Mutating Captures

एक closure जो एक captured variable को mutate करता है FnMut implement करता है; इसे call करने के लिए closure रखने वाला variable खुद mut होना चाहिए।

उदाहरण: FnMut: Mutating Captures

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare a mutable variable `count`, initialized to `0`
    let mut count = 0;
    // Declare a mutable variable `increment`, initialized to `|| {`
    let mut increment = || {
        count += 1;
        // Print "count is now {}" to the console, substituting in `count` (with a trailing newline)
        println!("count is now {}", count);
    };
    increment();
    increment();
}

FnOnce: Consuming Captures

एक closure जो अपने अंदर से एक captured variable को move करता है (उदाहरण के लिए, owned data return करना) सिर्फ FnOnce implement करता है, मतलब इसे ज़्यादा से ज़्यादा एक बार call किया जा सकता है।

उदाहरण: FnOnce: Consuming Captures

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `text`, set to `String::from("consumed")`
    let text = String::from("consumed");
    // Declare an immutable variable `consume`, set to `move || {`
    let consume = move || {
        // Declare an immutable variable `owned`, set to `text`
        let owned = text;
        // Print "Consumed inside closure: {}" to the console, substituting in `owned` (with a trailing newline)
        println!("Consumed inside closure: {}", owned);
    };
    consume();
}

Forcing Ownership with move

move keyword एक closure को यह capture करने वाली हर variable की ownership लेने पर मजबूर करता है, उन्हें borrow करने के बजाय, जो तब ज़रूरी है जब closure को अपने original scope से ज़्यादा जीना हो।

उदाहरण: Forcing Ownership with move

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `data`, set to `vec![1, 2, 3]`
    let data = vec![1, 2, 3];
    // Declare an immutable variable `owns_data`, set to `move || println!("Owned inside closure: {:?}", data)`
    let owns_data = move || println!("Owned inside closure: {:?}", data);
    owns_data();
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. एक FnOnce closure को एक से ज़्यादा बार call करने की कोशिश करना -- definition से यह सिर्फ एक बार call हो सकता है।
  2. Function signature में Fn मांगना जब pass किया गया closure असल में captured state mutate करने की ज़रूरत रखता हो, इसके बजाय FnMut मांगते हुए।
  3. यह भूल जाना कि move keyword एक closure को captured variables की ownership लेने पर मजबूर करता है बजाय उन्हें borrow करने के।
चैप्टर सारांश
  • Fn closures बार-बार call किए जा सकते हैं और सिर्फ captured variables को immutably borrow करते हैं।
  • FnMut closures बार-बार call किए जा सकते हैं और captured variables mutate कर सकते हैं।
  • FnOnce closures सिर्फ एक बार call किए जा सकते हैं, क्योंकि वे captured variables consume (move) करते हैं।
  • move keyword एक closure को इसके capture किए variables की ownership लेने पर मजबूर करता है बजाय उन्हें borrow करने के।
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.