将Vec <T>转换为&[T]的安全方法是什么?

Val*_*uca 1 rust

如何在不在内存中移动它的情况下为向量的基础堆分配分配生命周期?

我发现这是最简单的方法

pub fn heap_slice<'a, T:'a>(x: Vec<T>) -> &'a [T] {
    use std::mem::forget;
    use std::slice::from_raw_parts;
    x.shrink_to_fit();
    let ptr = x.ptr();
    let len = x.len();
    forget(x);
    unsafe{ from_raw_parts(ptr,len) };
}
Run Code Online (Sandbox Code Playgroud)

但这确实unsafe在stdlib之外调用,这通常是不受欢迎的.有安全的方法吗?

我看到的into_boxed_slice是大致相同的事情.但是,&[T]一旦它是一个,我该如何恢复并分配它Box<[T]>

Fra*_*gné 6

slice(&'a [T])应该表示由另一个对象(例如a Vec<T>或a Box<[T]>)拥有的某个数组的视图.这就是为什么引用有一个生命周期参数,Vec<T>Box<[T]>不是.

切片"丢弃"时,不会释放内存,因为切片不拥有内存.因此,您的函数会导致向量的存储泄漏.您不能只是"奇怪地"为切片"生命分配"生命周期并使编译器插入代码以释放堆分配.试想一下,复制切片会发生什么?

Rust会自动将矢量或盒装切片强制转换为需要切片的上下文中的切片(除非涉及泛型),所以实际上没有理由违反规则并在应该返回向量时返回切片或者盒装切片.

也许你正在编写一个库,你担心返回一个向量会暴露一些实现细节吗?好吧,这样想吧:如果你用C语言编写库,你会使用原始指针,但是你必须在API文档中写入调用者是否应该调用某个函数(以及哪一个)来清理资源与否.在Rust中,我们使用正确的返回类型对这些指令进行编码,以便程序员不必担心它.

你能否至少提供一个代码示例如何借用Box<[T]>as_ref()或者borrow()不允许终身分配

借用a的最短方式Box<[T]>是写&x&*x(在哪里x是a Box<[T]>).&x产生一个类型的值&Box<[T]>,可以强制执行,&[T]因为它Box实现了Deref特征.

要从函数返回具有有效生命周期参数的切片,必须将其链接到函数输入参数之一的lifetime参数.如果你将一个Box<[T]>by值传递给函数,那么就没有你可以链接到的生命周期,因为Rust希望Box在函数结束时删除它(你可以通过调用来防止这种情况发生mem::forget,但编译器无法推断) .你总是可以传递Box<[T]>引用(即&Box<[T]>),但这只会引入一个不必要的间接层,所以你的函数应该只接受&[T].