Note that the slice is unsized. I'm fine with doing a memory allocation/copy, or transferring ownership.
I know that to make simply an Rc<[u8]>
, I can use Rc::from(Vec::into_boxed_slice(Vec::from(x)))
, but this approach doesn't work with the added RefCell
. I note that RefCell<T>
allows T: ?Sized
, but it seems like in practice it's hard to actually construct a RefCell containing an unsized type?
RefCell
doesn't use indirection like Box
or Rc
, but instead it stores it's data on the stack. Here is a simplified definition of RefCell
and UnsafeCell
(both from the 1.70.0
version).
pub struct RefCell<T: ?Sized> {
borrow: Cell<BorrowFlag>,
value: UnsafeCell<T>,
}
#[repr(transparent)]
pub struct UnsafeCell<T: ?Sized> {
value: T,
}
RefCell can hold T
s that are not Sized
, but then it itself becomes !Sized
. There might be some way to create (some indirection) RefCell<[T]>
using unsafe
code, but I doubt It can be done safely.
The easiest solution, I believe, would be to use RefCell<Box<[T]>>
instead. Box
is sized, so when you have it, you can trivially construct RefCell
containing it. Note, that you have almost written this solution in your question, because Vec::into_boxed_slice(Vec::from(x))
doesn't return [T]
(as it is !Sized
), but rather Box<[T]>
which you then can store inside Rc
(or RefCell
).
As a shorthand you can create Box<[T]>
using impl From<&[T]> for Box<[T]>, and just write Box::from(slice)
.
To put it all together here's a snippet that you can use.
let slice: &[i32] = &[];
let boxed: Box<[i32]> = Box::from(slice);
let cell: RefCell<Box<[i32]>> = RefCell::new(boxed);
let cell: Rc<RefCell<Box<[i32]>>> = Rc::new(cell);
As a final note remember that when you have Box<[T]>
you can obtain a &mut [T]
from it using DerefMut, so you can change elements of the slice, but you cannot extend or shorten it. To do that you would need a Vec
.
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