拥有一些数据和对数据的引用的结构 [英] Struct that owns some data and a reference to the data
问题描述
对象的构造分配了该对象生命周期所需的数据,但也创建了另一个需要保留对数据的引用的对象:
Construction of an object allocates data needed for lifetime of that object, but also creates another object that needs to keep references to the data:
pub fn new() -> Obj {
let data = compute();
Obj {
original: data,
processed: AnotherObj {
reference: &data
}
}
}
可以用 Rust 的术语来表达吗?
Is it possible to express this in Rust's terms?
这里我希望 Obj
、AnotherObj
和 data
具有相同的生命周期,当然比 new()
调用.
Here I'd like Obj
, AnotherObj
and data
to have the same lifetime, and of course outlive the new()
call.
推荐答案
基于您的要求的原始结构设计可能如下所示:
A raw design of the structs based on your requirements might look like this:
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
成为生命周期原始
.但是,您必须为 Obj<'a>
提供生命周期,因此您必须指定 Obj<'tbc>
其中 'tbc
是要创建的 Obj
的生命周期.
However it's very tricky to get working (personally, I wasn't able to) because you want the 'a
in AnotherObj<'a>
to be the lifetime of original
. However you must supply a lifetime to Obj<'a>
and thus you would have to specify Obj<'tbc>
where 'tbc
is the lifetime of the Obj
to be created.
我建议以下替代方案:
为什么不呢?Obj
将拥有 AnotherObj
,因此它仍然可以访问 original
作为嵌套子项:
Why not? Obj
will own AnotherObj
, so it can still have access to original
as a nested child:
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.共享指针设计
直接使用引用计数的指针:
2. Shared pointer design
Straightforward use of refcounted pointers:
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 神的安心,因此我不推荐这第三个选项.为了完整起见,我仍然把它贴在这里.注意:它可以编译,但我从来没有在运行时测试过它,所以它可能会咬人.下面只有安全代码,但是当您想取消引用原始指针时,您必须进入 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
}
这篇关于拥有一些数据和对数据的引用的结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!