Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to create a RefCell<Any>?

Tags:

rust

Is it possible to create something of type RefCell<Any> in Rust? I tried the following:

fn test2<T : Any>(x : T) -> RefCell<Any>{
    return RefCell::new(x) as RefCell<Any>
}

But I get the following error:

error: the trait `core::marker::Sized` is not implemented for the type `core::any::Any + 'static` [E0277]
<anon>:8 fn test2<T : Any>(x : T) -> RefCell<Any>{

The documentation for RefCell includes the following

pub struct RefCell<T> where T: ?Sized {
    // some fields omitted
}

Which leads me to believe (along with the answer from this question) that such a thing is possible. I also tried:

fn test1<T : Any>(x : T) -> Box<Any>{
    return Box::new(x) as Box<Any>
}

which works just fine. Both Box and RefCell seem to have similar bounds, so I'm not quite sure what I'm missing here. Any help would be much appreciated. I have this in a Rust Playground, if that is helpful.

like image 932
Matt Avatar asked Feb 10 '16 00:02

Matt


People also ask

How does the refcell<T> function work?

The RefCell<T> keeps a record of how many Ref<T> and Refmut<T> smart pointers are currently active. Whenever the borrow () method is called, then the RefCell<T> increases the count of how many immutable borrows are active. When the Rc<T> goes out of the scope, then RefCell<T> decreases the count by one.

Is it possible to use a &refcell without a RC?

A RefCell without a Rc is possible but it can become very painful. You have to add a lot of lifetimes everywhere to make the compiler happy about your &RefCell. So, it's easier to put it into an Rc. Definitely, it can easily be misused, especially if one's new to Rust and reaches for it by default.

Should I ever use refcell in rust?

Until you have a fair amount of experience writing Rust code, it's normally a good idea to avoid using things like RefCell. Of course, you will sometimes run into situations where you have absolutely no choice.

Is self mutable in a refcell?

This call borrows RefCell mutably (at compile-time) so there is no need for dynamic checks. However be cautious: this method expects self to be mutable, which is generally not the case when using a RefCell. Take a look at the borrow_mut method instead if self isn’t mutable.


2 Answers

Box has the trait std::ops::CoerceUnsized, which allows to cast to Box<Any>. RefCell does not, so you can't.

Of course you can do this:

let x = RefCell::new( String::new() );
let x = &x as &RefCell<Any>;

So you can have a RefCell<Any>, but cannot construct one or coerce to one, only coerce references.

like image 126
Cecilio Pardo Avatar answered Sep 27 '22 23:09

Cecilio Pardo


RefCell<Any> is an unsized type; you can’t have an actual instance of an unsized type—how much stack space will it take? This is the same as the way in which you can’t return Any but must rather return Box<Any>; so also you can’t return RefCell<Any> but must return something like Rc<RefCell<Any>>. The likes of RefCell<Box<Any>> would work fine too, because a RefCell of a sized type is itself sized.

Demonstration.

like image 32
Chris Morgan Avatar answered Sep 27 '22 21:09

Chris Morgan