RefCell<T>

If you need Cell-like features for non-Copy types, there is the RefCell type. It uses a read/write pattern similar to how borrowing works, but moves the checks to runtime, which is convenient but not zero-cost. RefCell hands out references to the value, instead of returning things by value as is the case with the Cell type. Here's a sample program that 

// refcell_basics.rs

use std::cell::RefCell;

#[derive(Debug)]
struct Bag {
item: Box<u32>
}

fn main() {
let bag = RefCell::new(Bag { item: Box::new(1) });
let hand1 = &bag;
let hand2 = &bag;
*hand1.borrow_mut() = Bag { item: Box::new(2)};
*hand2.borrow_mut() = Bag { item: Box::new(3)};
let borrowed = hand1.borrow();
println!("{:?}", borrowed);
}

As you can see, we can borrow bag, mutably from hand1 and hand2 even though they are declared as immutable variables. To modify the items in bag, we called borrow_mut on hand1 and hand2. Later, we borrow it immutably and print the contents.

The RefCell type provides us with the following two borrowing methods:

  • The borrow method takes a new immutable reference
  • The borrow_mut method takes a new mutable reference

Now, if we try to call both of the methods in the same scope: by changing the last line in the preceding code to this:

println!("{:?} {:?}", hand1.borrow(), hand1.borrow_mut());

We get to see the following upon running the program:

thread 'main' panicked at 'already borrowed: BorrowMutError', src/libcore/result.rs:1009:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

A runtime panic ! This is because of the same ownership rule of having exclusive mutable access. But, for RefCell this is checked at runtime instead. For situations like this, one has to explicitly use bare blocks to separate the borrows or use the drop method to drop the reference.

Note: The Cell and RefCell types are not thread safe. This simply means that Rust won't allow you to share these types in multiple threads.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset