比如,我们经常看到Vec类型,但取转其裸指针,经常会看到into_boxed_slice()方法,这是为何?
use std::{fmt, slice};#[derive(Clone, Copy)]
struct RawBuffer {ptr: *mut u8,len: usize,
}impl From<Vec<u8>> for RawBuffer {fn from(vec: Vec<u8>) -> Self {let slice = vec.into_boxed_slice();Self {len: slice.len(),// into_raw 之后,Box 就不管这块内存的释放了,RawBuffer 需要处理释放ptr: Box::into_raw(slice) as *mut u8,}}
}
其实,你看标准文档,就很清楚,
pub fn into_boxed_slice(self) -> Box<[T], A>//Converts the vector into Box<[T]>.//If the vector has excess capacity, its items will be moved into a newly-allocated buffer with exactly the right capacity.
也就是说,转成了Box<[T]>后,指针所指向的类型,更简短了。
use std::{fmt, slice};
// 从*mut u8 恢复
fn as_ref<'a,T>(pointer: *mut T, len: usize) -> &'a [T] { unsafe { slice::from_raw_parts(pointer, len) }
}
// 从vec<T>转化Box<[T]>后得到相应的裸指针
fn get_raw_pointer_from_vec_by_box<T>(vec:Vec<T>) ->*mut T{let slice = vec.into_boxed_slice();Box::into_raw(slice) as *mut T
}
// 从vec<T>的as_mut_ptr()得到的裸指针
fn get_raw_pointer_from_vec_by_as_mut<T:Copy>( vec:&mut Vec<T>) ->*mut T{let ptr = vec.as_mut_ptr();//不能直接用,相当于是一个初始化的指针let counts = vec.len();let size = vec.capacity();// Initialize elements via raw pointer writes, then set length.unsafe {for i in 0..counts {*ptr.add(i) = vec[i];}vec.set_len(size);}ptr}fn main(){let mut vec = Vec::with_capacity(10);vec.extend([1_u8, 2, 3]);//查看into_boxed_slice()后堆上数据的空间情况assert!(vec.capacity() >= 10);let vec0 = vec.clone();let slice = vec0.into_boxed_slice() ;// Box<[u8]> ,clone()不会影响vec值的存在assert_eq!(slice.clone().into_vec().capacity(), 3); // slice clone后不会影响slice值存在// 指针类型1:通过box[T]->转换成&[T]let vec1 = vec.clone();let pointer_from_box = get_raw_pointer_from_vec_by_box(vec1);//获得相应的*mut u8let slice_object_from_box = as_ref(pointer_from_box,slice.len()) ;println!("slice_object_from_box :{:?} ",slice_object_from_box);// 指针类型2:通过 as_mut 直接转 *mut T,再转换成&[T]let mut vec2 = vec.clone();let pointer_from_as_mut = get_raw_pointer_from_vec_by_as_mut(&mut vec2);let slice_object_from_as_mut = as_ref(pointer_from_as_mut,vec.len());//vec.capacity()) ;println!("slice_object_from_as_mut: {:?} ",slice_object_from_as_mut);}
看看输出了啥?
Running `target/debug/playground`Standard Outputslice_object_from_box :[1, 2, 3]
slice_object_from_as_mut: [1, 2, 3]