Rust 转换Vec的安全方法是什么<;T>;致a&;[T]

Rust 转换Vec的安全方法是什么<;T>;致a&;[T],rust,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(); forg

如何在不移动内存的情况下将向量的底层堆分配分配给生存期

我发现最简单的方法就是

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) };
}
pub fn heap_slice(x:Vec)->&'a[T]{
使用std::mem::忘记;
使用std::slice::from_raw_parts;
x、 收缩到合适的位置();
设ptr=x.ptr();
设len=x.len();
忘记(x);
不安全{来自原始零件(ptr,len)};
}
但这确实会在stdlib之外调用
不安全的
,这通常是不受欢迎的。有安全的方法吗

我看到
到_boxed_slice
做的事情大致相同。但是我如何恢复
&[T]
并在它成为
框之后分配它一个生存期呢?

一个切片(
&'a[T]
)应该表示另一个对象(例如
Vec
)拥有的某个数组中的视图。这就是为什么引用有一个生存期参数而
Vec
Box
没有

当一个片被“丢弃”时,不会释放内存,因为该片不拥有内存。因此,您的函数会导致向量的存储泄漏。您不能只是“神奇地分配”一个片的生存期,并让编译器插入代码来释放堆分配。试想一下,复制切片时会发生什么

Rust会在需要切片的上下文中自动将向量或装箱切片强制为切片(涉及泛型时除外),因此实际上没有理由违反规则,在应该返回向量或装箱切片时返回切片

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


您能否至少提供一个代码示例,说明如何借用
<代码>as_ref()
借用()
不允许生命周期分配

盒子
借用的最短方法是写
&x
&x
(其中
x
盒子
&x
生成类型为
&Box
的值,该值可以强制为
&T]
,因为
Box
实现了该特征

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

一个切片(
&A[T]
)应该表示另一个对象所拥有的某个数组中的视图(例如
Vec
Box
)。这就是为什么引用有生存期参数而
Vec
Box
没有

当一个切片被“丢弃”时,不会释放内存,因为该切片不拥有内存。因此,您的函数会导致向量的存储泄漏。您不能只是“神奇地”为切片分配一个生存期,并让编译器插入代码以释放堆分配。试想一下,复制该切片时会发生什么

Rust会在需要切片的上下文中自动将向量或装箱切片强制为切片(涉及泛型时除外),因此实际上没有理由违反规则,在应该返回向量或装箱切片时返回切片

也许您正在编写一个库,并且您担心返回一个向量会暴露一些实现细节?那么,请这样想:如果您是用C编写库,您将使用原始指针,但是您必须在API文档中编写调用方是否应该调用某个函数(以及哪个函数)在Rust中,我们使用正确的返回类型对这些指令进行编码,这样程序员就不必担心了


您是否可以至少提供一个代码示例,说明如何借用
作为\u ref()
借用()

借用的最短方法是写入
&x
&x
(其中
x
是一个
)。
&x
生成一个
&Box
类型的值,该值可以强制为
&T]
,因为
实现了该特性


为了从函数返回具有有效生存期参数的切片,必须将其链接到函数输入参数之一的生存期参数。如果您通过值将
传递给函数,则没有可以链接的生存期,因为Rust希望在函数结束时删除
(您可以通过调用
mem::forget
来防止这种情况发生,但编译器无法对此进行推理)。您可以始终通过引用(即
&Box
)传递
框,但这只会引入不必要的间接层,因此您的函数应该只接受
&T]
相反。

好的,很酷,所以基本上我需要包装一个片段并添加一个drop trait,谢谢!(我正在尝试使用TLS消息包,它们都在一起,一旦组合起来就只有几KB,我不希望重新分配