Kidsunbo
Kidsunbo

Reputation: 1054

Should I avoid to use Rc and RefCell when possible in Rust?

Rust offers borrow check at compile time. But if using Rc and RefCell, the check will be defered at runtime and a panic will be thrown when the program breaks the rule. Just like this:

use std::rc::Rc;
use std::cell::RefCell;

fn func1(reference: Rc<RefCell<String>>){
    let mut a = reference.borrow_mut();
    *a = String::from("func1");
    func2(reference.clone());
}

fn func2(reference: Rc<RefCell<String>>){
    let mut a = reference.borrow_mut();
    *a = String::from("func2");
    func3(reference.clone());
}

fn func3(reference: Rc<RefCell<String>>){
    let mut a = reference.borrow_mut();
    *a = String::from("func3");
}


fn main() {
    let a = Rc::new(RefCell::new(String::from("hello")));
    func1(a.clone());
}

This code is still leaving the bug (maybe not a bug) to runtime and panicked. So should I avoid using Rc and RefCell as much as possible? And does this code count as safe code?

Upvotes: 5

Views: 2288

Answers (1)

Billbucket
Billbucket

Reputation: 175

Since Rc and RefCell allow you to compile code that will potentially panic at runtime, they're not to be used lightly. You could use try_borrow_mut instead of borrow_mut to avoid the panic and handle the result yourself.

That being said, even if you prevent all panicking, Rc and RefCell have a cost at runtime since they keep a reference counter. In many cases you can avoid them by rewriting your code in a more rusty way.

fn func1(mut string: String) -> String {
    string = "func1".into();
    func2(string)
}

fn func2(mut string: String) -> String {
    string = "func2".into();
    func3(string)
}

fn func3(string: String) -> String {
    "func3".into()
}

fn main() {
    let a = func1("hello".into());
}

Is much simpler, and safe. Rust will take care of optimizations for you.

To answer your last question, using borrow_mut is not considered as unsafe code since the code compiles even with the #![forbid(unsafe_code)] directive

Upvotes: 6

Related Questions