borrow and borrow_mut
- Rust course
- Intermediate
- Lesson 37/115
- 4 min
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()); // 6A 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); // safeRule: 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
use std::cell::RefCell;
fn main() {
// buraya yaz
}Sample solution
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
let sonuc = c.____(); // Err(BorrowMutError)
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 |