我有一个结构
struct Foo<'a> {
buf: [u8, ..64],
slice: &'a [u8]
}
切片应该指向结构的buf
字段。有没有办法构建这样的结构?类似的东西:
impl<'a> Foo<'a> {
fn new() -> Foo<'a> {
Foo {
buf: [0, ..64],
slice: ???? /* I don't know what to write here */
}
}
如果我尝试执行以下操作,借用检查器会(正确地)抱怨,因为切片的生命周期将比结构更短。
impl<'a> Foo<'a> {
fn new() -> Foo<'a> {
let buf = [0, ..64];
Foo {
buf: buf,
slice: buf.slice_from(0)
}
}
}
我意识到,对于这个简单的情况,我可以保留偏移并手动调用切片函数:
struct Foo {
buf: [u8, ..64],
slice_from: uint,
slice_to: uint
}
然而,这个问题只是对拥有数据的结构的更一般用例的简化,并且引用了相同的数据,并且我想知道在Rust中是否可以(以安全的方式)。
答案 0 :(得分:7)
不,你不能安全地做到这一点,因为通常这种结构是不可移动的。假装它是可能的,你可以创建这样的结构:
let foo = Foo {
buf: [0, ..64],
slice: obtain_slice_somehow()
};
slice
字段现在是buf
字段的一个片段,特别是它包含一个指向buf
的指针,该指针当前位于堆栈中。现在将foo
放入一个框并从函数中返回:
return Box::new(foo);
foo
值现在移动到堆,函数退出,释放堆栈内存。但是,slice
指针未调整指向堆,因为一般情况下不可能这样做,因此它会悬空,违反内存安全。