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.
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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With