CodeBlanks Logo Icon CodeBlanks

borrow and borrow_mut

Use RefCell's borrow and borrow_mut methods.

borrow and borrow_mut

RefCell counts how many readers and writers exist at any moment. Calling borrow_mut() while a reader is alive panics: "already borrowed: BorrowMutError". To check instead of panicking, try_borrow and try_borrow_mut return a Result:

let c = RefCell::new(5);
let r1 = c.borrow();
println!("{}", c.try_borrow_mut().is_err());   // true: a reader exists
drop(r1);
*c.borrow_mut() += 1;                         // free now
println!("{}", c.borrow());                   // 6

A common mistake

Keeping a Ref in a variable and trying to write in the same scope produces code that compiles but crashes at runtime:

let liste = RefCell::new(vec![1]);
let ilk = liste.borrow();          // the reader is still alive
// liste.borrow_mut().push(2);     // panic!
let n = ilk[0];
drop(ilk);
liste.borrow_mut().push(n + 1);    // safe

Rule: copy the value, or limit the borrow with a braced block.

Practice Safe attempt

Create RefCell::new(5). In an inner block take borrow() and print the value and the result of try_borrow_mut().is_err() separated by a space. After the block, increment the value by 1 with borrow_mut and print it.

Starter code

main.rs
use std::cell::RefCell;

fn main() {
    // buraya yaz
}

Sample solution

main.rs
use std::cell::RefCell;

fn main() {
    let c = RefCell::new(5);
    {
        let r1 = c.borrow();
        let cakisma = c.try_borrow_mut().is_err();
        println!("{} {}", *r1, cakisma);
    }
    *c.borrow_mut() += 1;
    println!("{}", c.borrow());
}

Expected output

5 true
6

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What happens with <code>let a = c.borrow(); let b = c.borrow();</code>?

  • No problem; multiple readers are allowed Correct answer
  • Panic
  • Compile error
  • b becomes None

Explanation: The rules match the compile-time rules: many readers are fine, a writer must be alone.

2 Try without panic

Question
let sonuc = c.____();   // Err(BorrowMutError)
Answer
let sonuc = c.try_borrow_mut();   // Err(BorrowMutError)

Explanation: try_borrow_mut returns Err instead of panicking on a conflict.

3 Case and result

Term Meaning
borrow + borrow Allowed
borrow + borrow_mut Panic
borrow + try_borrow_mut Err
drop(r) + borrow_mut Works

All lessons in Intermediate