我包装,有一个C库context
和device
对象。 所述context
对象需要活得比的device
,因为该对象device
保持一个内部参考context
。
为了表达这一点,我使用的是PhantomData
场的Device
包装:
use std::marker::PhantomData;
struct Context;
impl Context {
fn open_device<'a>(&'a self) -> Device<'a> {
Device { _context: PhantomData, }
}
}
struct Device<'a> {
_context: PhantomData<&'a Context>,
}
现在,在我的客户端代码,我想有一个同时拥有了一个struct Context
和Device
对象。 但由于Device
拥有一个引用(假的)的Context
,我不能做到这一点(见这个问题)。 但是,这是一个不必要的限制,因为该Device
结构实际上并不包含对一个参考Context
。
那么,怎样才能将我的寿命扎Device
的寿命Context
的方式,可以让我在一个结构持有他们两个?
截至今天,锈不能够表达一生是指在同一个结构定义的对象,所以不可能宣布参加适当的寿命Device
成员。
而不是直接在结构存储这两个对象,你可以存储,而不是对这些结构引用? (如果你想返回的是结构的函数这是行不通的。)
struct Both<'a: 'b, 'b> {
context: &'a Context,
device: &'b Device<'a>,
}
另一种选择是声明Device
为具有Context
与'static
寿命(我用'static
,因为它是一个名称的唯一寿命),但总是用一种方法来‘投’的Device
变成一个与适当的寿命参数,而不是直接使用领域。
struct Both {
context: Context,
device: Device<'static>,
}
impl Both {
fn get_device<'a>(&'a self) -> &'a Device<'a> {
&self.device
}
}
事实上,由于寿命省音,没有必要明确指定的寿命参数get_device
(同样为您open_device
方法,顺便说一句):
impl Both {
fn get_device(&self) -> &Device {
&self.device
}
}
这里只是一个疑难杂症:你需要使用transmute
撒谎设备的生命周期参数在初始化的结构。
use std::mem;
fn get_both() -> Both {
let context = Context; // could also be a parameter
let device: Device<'static> = unsafe { mem::transmute(context.open_device()) };
Both {
context: context,
device: device,
}
}
您可能还需要考虑具有Both
包含结构Device
不具有寿命参数,然后包裹在另一个结构确实有一辈子的参数和返回从一个方法。
use std::marker::PhantomData;
use std::mem;
struct Context;
impl Context {
fn open_device(&self) -> Device {
Device
}
}
struct Device;
struct DeviceWrapper<'a> {
_context: PhantomData<&'a Context>,
device: &'a Device,
}
struct Both {
context: Context,
device: Device,
}
impl Both {
fn get_device(&self) -> DeviceWrapper {
DeviceWrapper { _context: PhantomData, device: &self.device }
}
}
fn get_both() -> Both {
let context = Context;
let device = context.open_device();
Both {
context: context,
device: device,
}
}
(事实上, DeviceWrapper
可能不需要_context
成员,因为DeviceWrapper
的一生被绑定到的Both
了。)