← Back to Rust Course | Chapter 13: Smart Pointers & Unsafe | Lesson 3 of 7

RefCell और Interior Mutability क्या है

RefCell आपको एक reference के ज़रिए भी एक value बदलने देता है जो read-only होनी चाहिए, लेकिन यह rules को आगे से नहीं बल्कि आपके program चलते समय जांचता है।
Syntax
rust
let name = RefCell::new(value);
name.borrow();
name.borrow_mut();

let shared = Rc::new(RefCell::new(value));

Mutating Through RefCell

RefCell<T> आपको .borrow_mut() के ज़रिए इसके inner data का एक mutable reference पाने देता है, भले ही RefCell खुद immutably bound हो, borrow checking को runtime पर move करते हुए।

उदाहरण: Mutating Through RefCell

markup
// Bring `std::cell::RefCell` into scope
use std::cell::RefCell;

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `cell`, set to `RefCell::new(5)`
    let cell = RefCell::new(5);
    *cell.borrow_mut() += 1;
    // Print "{}" to the console, substituting in `cell.borrow()` (with a trailing newline)
    println!("{}", cell.borrow());
}

Runtime Borrow Checking

Compile-time references के विपरीत, RefCell program चलते समय borrowing rules जांचता है: एक साथ दो conflicting borrows की कोशिश करना एक compile error के बजाय एक panic का कारण बनता है।

उदाहरण: Runtime Borrow Checking

markup
// Bring `std::cell::RefCell` into scope
use std::cell::RefCell;

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `cell`, set to `RefCell::new(String::from("hello"))`
    let cell = RefCell::new(String::from("hello"));
    {
        // Declare an immutable variable `borrowed`, set to `cell.borrow()`
        let borrowed = cell.borrow();
        // Print "Reading: {}" to the console, substituting in `borrowed` (with a trailing newline)
        println!("Reading: {}", borrowed);
    }
    cell.borrow_mut().push_str(", world");
    // Print "{}" to the console, substituting in `cell.borrow()` (with a trailing newline)
    println!("{}", cell.borrow());
}

Combining Rc and RefCell

Rc<RefCell<T>> एक आम pattern है जो कई owners को उसी data तक shared access देता है, जबकि फिर भी उनमें से किसी को RefCell के ज़रिए इसे mutate करने देता है।

उदाहरण: Combining Rc and RefCell

markup
// Bring `std::cell::RefCell` into scope
use std::cell::RefCell;
// Bring `std::rc::Rc` into scope
use std::rc::Rc;

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `shared`, set to `Rc::new(RefCell::new(0))`
    let shared = Rc::new(RefCell::new(0));
    // Declare an immutable variable `clone_a`, set to `Rc::clone(&shared)`
    let clone_a = Rc::clone(&shared);
    *clone_a.borrow_mut() += 10;
    // Print "Value: {}" to the console, substituting in `shared.borrow()` (with a trailing newline)
    println!("Value: {}", shared.borrow());
}

Why Interior Mutability Exists

Interior mutability उन situations के लिए एक escape hatch प्रदान करता है जहां Rust के सख्त compile-time borrowing rules बहुत rigid हैं, जैसे कई जगहों से update होने वाला एक shared cache, कुछ checks को runtime पर move करने की कीमत पर।

उदाहरण: Why Interior Mutability Exists

markup
// Bring `std::cell::RefCell` into scope
use std::cell::RefCell;

// Define a struct `Cache` to group related fields together
struct Cache {
    value: RefCell<Option<i32>>,
}

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `cache`, set to `Cache { value: RefCell::new(None) }`
    let cache = Cache { value: RefCell::new(None) };
    *cache.value.borrow_mut() = Some(42);
    // Print "{:?}" to the console, substituting in `cache.value.borrow()` (with a trailing newline)
    println!("{:?}", cache.value.borrow());
}
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. एक RefCell को एक समय में दो बार mutably borrow करना, जो compile तो ठीक होता है लेकिन runtime पर एक borrow error के साथ panic करता है।
  2. RefCell उपयोग करना जब एक plain &mut reference भी उतना ही काम करता, अनावश्यक runtime checking overhead जोड़ते हुए।
  3. यह भूल जाना कि RefCell अकेले owners में sharing allow नहीं करता -- यह आमतौर पर shared, mutable-दिखने वाले data के लिए Rc के साथ combined होता है।
चैप्टर सारांश
  • RefCell<T> एक immutable reference के ज़रिए भी data mutate करने देता है, borrow checking को compile time से runtime पर move करते हुए।
  • .borrow() और .borrow_mut() runtime-checked references return करते हैं, और borrowing rules तोड़ना एक compile error के बजाय एक panic का कारण बनता है।
  • Rc<RefCell<T>> shared ownership को interior mutability के साथ combine करने वाला एक आम pattern है।
  • Interior mutability को जानबूझकर उपयोग किया जाना चाहिए, क्योंकि misuse compile-time errors को runtime panics में बदल देता है।
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 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.