Hello everyone, im learnning rust, Rust very good. But I get a problem when understand the implement for ConvertVec. the code like [ignore some comments].
impl<T: Clone> ConvertVec for T {
default fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A> {
struct DropGuard<'a, T, A: Allocator> {
vec: &'a mut Vec<T, A>,
num_init: usize,
}
impl<'a, T, A: Allocator> Drop for DropGuard<'a, T, A> {
#[inline]
fn drop(&mut self) {
//❓ why need set_len ? i think `vec.set_len(s.len());` is enough
unsafe {
self.vec.set_len(self.num_init);
}
}
}
let mut vec = Vec::with_capacity_in(s.len(), alloc);
//❓ why need DropGuard ? i think that Vec is enough
let mut guard = DropGuard { vec: &mut vec, num_init: 0 };
let slots = guard.vec.spare_capacity_mut();
for (i, b) in s.iter().enumerate().take(slots.len()) {
guard.num_init = i;
slots[i].write(b.clone());
}
core::mem::forget(guard);
unsafe {
**vec.set_len(s.len());**
}
vec
}
}
one question.
I known core::mem::forget(guard);
will tell compile do not "drop" value. but the drop method in DropGuard
is only set len for vector , it's duplicate setted in unsafe code. so why we need set len twice ?
other question is why we need DropGuard
rather than use directly Vec
,i konw like this
impl<T: Clone> ConvertVec for T {
#[inline]
default fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A> {
let mut vec = Vec::with_capacity_in(s.len(), alloc);
let slots = vec.spare_capacity_mut();
for (i, b) in s.iter().enumerate().take(slots.len()) {
slots[i].write(b.clone());
}
unsafe {
vec.set_len(s.len());
}
vec
}
}
Can anyone give me some tip or suggestion about it ?