拥有一些数据和对数据的引用的结构
Struct that owns some data and a reference to the data
对象的构造会分配该对象生命周期所需的数据,但也会创建另一个需要保留对数据的引用的对象:
pub fn new() -> Obj {
let data = compute();
Obj {
original: data,
processed: AnotherObj {
reference: &data
}
}
}
可以用 Rust 的术语来表达吗?
在这里,我希望 Obj
、AnotherObj
和 data
具有相同的生命周期,当然比 new()
调用还长。
基于您的要求的结构的原始设计可能如下所示:
struct AnotherObj<'a> {
original: &'a Vec<i8>, // Let's agree on Vec<i8> as your "data" type.
}
struct Obj<'a> {
original: Vec<i8>, // <-------------------+
processed: AnotherObj<'a>, // should point here --+
}
然而,开始工作非常棘手(就我个人而言,我无法做到),因为您希望 AnotherObj<'a>
中的 'a
成为 original
的生命周期。但是,您必须为 Obj<'a>
提供生命周期,因此您必须指定 Obj<'tbc>
,其中 'tbc
是要创建的 Obj
的生命周期。
我建议以下替代方案:
1。让 AnotherObj 实际上 拥有 原来的
为什么不呢? Obj
将拥有 AnotherObj
,因此它仍然可以作为嵌套子项访问 original
:
pub struct AnotherObj {
original: Vec<i8>,
}
pub struct Obj {
processed: AnotherObj,
}
pub fn new() -> Obj {
let data = vec![1,2,3];
Obj {
processed: AnotherObj {
original: data,
// ...
}
}
}
// access as obj.processed.original, you can even create a getter `fn original(&self)`
2。共享指针设计
引用计数指针的直接使用:
use std::rc::Rc;
pub struct AnotherObj {
original: Rc<Vec<i8>>,
}
pub struct Obj {
original: Rc<Vec<i8>>,
processed: AnotherObj,
}
pub fn new() -> Obj {
let data = Rc::new(vec![1,2,3]);
Obj {
original: data.clone(),
processed: AnotherObj {
original: data.clone(),
}
}
}
3。使用原始指针
选项1.和2.会给你带来安全Rust大神的安心,所以我不推荐这第三个选项。为了完整起见,我仍然 post 在这里。注意:它可以编译,但我从未在运行时测试过它,所以它可能会咬人。下面只有安全代码,但是当您想取消引用原始指针时,您必须进入 unsafe
区域。
use std::ptr;
pub struct AnotherObj {
original: *mut Vec<i8>,
}
pub struct Obj {
original: Vec<i8>,
processed: AnotherObj,
}
pub fn new() -> Obj {
let data = vec![1,2,3];
let mut obj = Obj {
original: data,
processed: AnotherObj {
original: ptr::null_mut(),
}
};
obj.processed.original = &mut obj.original as *mut Vec<i8>;
obj
}
对象的构造会分配该对象生命周期所需的数据,但也会创建另一个需要保留对数据的引用的对象:
pub fn new() -> Obj {
let data = compute();
Obj {
original: data,
processed: AnotherObj {
reference: &data
}
}
}
可以用 Rust 的术语来表达吗?
在这里,我希望 Obj
、AnotherObj
和 data
具有相同的生命周期,当然比 new()
调用还长。
基于您的要求的结构的原始设计可能如下所示:
struct AnotherObj<'a> {
original: &'a Vec<i8>, // Let's agree on Vec<i8> as your "data" type.
}
struct Obj<'a> {
original: Vec<i8>, // <-------------------+
processed: AnotherObj<'a>, // should point here --+
}
然而,开始工作非常棘手(就我个人而言,我无法做到),因为您希望 AnotherObj<'a>
中的 'a
成为 original
的生命周期。但是,您必须为 Obj<'a>
提供生命周期,因此您必须指定 Obj<'tbc>
,其中 'tbc
是要创建的 Obj
的生命周期。
我建议以下替代方案:
1。让 AnotherObj 实际上 拥有 原来的
为什么不呢? Obj
将拥有 AnotherObj
,因此它仍然可以作为嵌套子项访问 original
:
pub struct AnotherObj {
original: Vec<i8>,
}
pub struct Obj {
processed: AnotherObj,
}
pub fn new() -> Obj {
let data = vec![1,2,3];
Obj {
processed: AnotherObj {
original: data,
// ...
}
}
}
// access as obj.processed.original, you can even create a getter `fn original(&self)`
2。共享指针设计
引用计数指针的直接使用:
use std::rc::Rc;
pub struct AnotherObj {
original: Rc<Vec<i8>>,
}
pub struct Obj {
original: Rc<Vec<i8>>,
processed: AnotherObj,
}
pub fn new() -> Obj {
let data = Rc::new(vec![1,2,3]);
Obj {
original: data.clone(),
processed: AnotherObj {
original: data.clone(),
}
}
}
3。使用原始指针
选项1.和2.会给你带来安全Rust大神的安心,所以我不推荐这第三个选项。为了完整起见,我仍然 post 在这里。注意:它可以编译,但我从未在运行时测试过它,所以它可能会咬人。下面只有安全代码,但是当您想取消引用原始指针时,您必须进入 unsafe
区域。
use std::ptr;
pub struct AnotherObj {
original: *mut Vec<i8>,
}
pub struct Obj {
original: Vec<i8>,
processed: AnotherObj,
}
pub fn new() -> Obj {
let data = vec![1,2,3];
let mut obj = Obj {
original: data,
processed: AnotherObj {
original: ptr::null_mut(),
}
};
obj.processed.original = &mut obj.original as *mut Vec<i8>;
obj
}