fn subslice(a: Arc<[T]>, begin: usize, end: usize) -> Arc<[T]> {
Arc::new(a[begin..end])
}
The above "obvious implementation" of the subslicing operation for Arc<[T]>
does not work because a[begin..end]
has type [T]
, which is unsized. Arc<T>
has the curious property that the type itself does not require T: Sized
, but the constructor Arc::new
does, so I'm at a loss for how to construct this subslice.
You can't.
To explain why, let's look at what Arc
actually is under the covers.
pub struct Arc<T: ?Sized> {
ptr: Shared<ArcInner<T>>,
}
Shared<T>
is an internal wrapper type that essentially amounts to " *const T
, but can't be zero"; so it's basically a &T
without a lifetime. This means that you can't adjust the slice at this level; if you did, you'd end up trying to point to an ArcInner
that doesn't exist. Thus, if this is possible, it must involve some manipulation of the ArcInner
.
ArcInner<T>
is defined as follows:
struct ArcInner<T: ?Sized> {
strong: atomic::AtomicUsize,
weak: atomic::AtomicUsize,
data: T,
}
strong
and weak
are just the number of strong and weak handles to this allocation respectively. data
is the actual contents of the allocation, stored inline. And that's the problem.
In order for your code to work as you want, Arc
would not only have to refer to data
by another pointer (rather than storing it inline), but it would also have to store the reference counts and data in different places, so that you could take a slice of the data, but retain the same reference counts.
So you can't do what you're asking.
One thing you can do instead is to store the slicing information alongside the Arc
. The owning_ref
crate has an example that does exactly this .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.