我有一个存储指向某些数据的原始指针的结构:
struct Foo<T> {
x: *const T
}
impl<T> Foo<T> {
fn new(x: &[T]) -> Foo<T> {
Foo {
x: &x[0] as *const T
}
}
}
数据实际上是一个切片,但我使用偏移方法来避免直接存储数据。构造函数将指向数据的指针放入字段中,并返回结构。但是,如果我尝试从函数返回Foo
:
fn foo() -> Foo<i32> {
let x = [1, 2, 3];
Foo::new(&x)
}
fn main() {
unsafe {
println!("{}", &*foo().x);
}
}
数据被过早删除,字段x
指向垃圾。我想要发生的是克隆的数据x
,并且只要结构存在,克隆就会存在。我怎么能做到这一点?
答案 0 :(得分:4)
你没有。
你正试图逃避指向堆栈数据的指针,如果你使用常规的借用指针,Rust会禁止你这样做。但是,通过使用原始指针和unsafe
,您已经有效地剥离了编译器通常会执行的各种保护。
你真的,真的不应该使用x
,除非你明白发生了什么。
如果不将其移出,也无法延长函数内创建的内容的生命周期。传递&i32
的指针(或借用)只是无法。
对此的修复只是不首先执行此操作。使用借用的指针(&[i32]
或i32
)或拥有的值(Vec<i32>
,&mut
)。
另一种可能性是在调用者中分配必要的存储空间并将foo
传递给foo
,然后您可以对其进行切片,变异和返回借用的子-slice到。当然,这要求您可以静态定义std
所需空间的上限,但这样的生命没有{{1}}。