Rust: Vec类型的into_boxed_slice()方法及其它

比如,我们经常看到Vec类型,但取转其裸指针,经常会看到into_boxed_slice()方法,这是为何?

use std::{fmt, slice};
use std::mem::size_of_val;

#[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]>后,指针所指向的类型,更简短了,丢弃多余的 capacity。
在这里插入图片描述

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(){
	//尽管size_of_val只是测试真实占用内存;不包括预分配的内存空间
    let vec_base = vec![1_u8, 2, 3];
    println!("vec_base size of val :{:?}",size_of_val(&vec_base));
    let mut vec = Vec::with_capacity(100);//预分配空间
    vec.extend([1_u8, 2, 3]);
    println!("vec size of val :{:?}",size_of_val(&vec));
    
    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 u8
    let 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 Output

vec_base size of val :24
vec size of val :24
slice_object_from_box :[1, 2, 3]  
slice_object_from_as_mut: [1, 2, 3] 

上面,还可以看到,实际分配内存和预分配内存不一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值