我正在尝试实现一个简单的特性,它返回对某些数据(GetData
(的引用。由于不同的原因,我需要实现这个特性,以参考我的类型(&Base<T>
(。我还希望有一个包装器类型,它拥有基类型并实现特性。
简化的示例如下:
// Trait
trait GetData<T> {
fn get_data(&self) -> &T;
}
// Base type
struct Base<T> {
pub data: T,
}
impl<T> GetData<T> for &Base<T> {
fn get_data(&self) -> &T {
&self.data
}
}
// Wrapper type owning a Base type
struct Wrapper<T> {
base: Base<T>,
//...
}
impl<T> GetData<T> for &Wrapper<T> {
fn get_data(&self) -> &T {
(&self.base).get_data() // E0515: returns a value referencing data owned by the current function
//&self.base.data // This works fine!
}
}
当为&Wrapper<T>
实现get_data
时,我从函数中返回了一个临时值。据我所知,&self.base
是由GetData::get_data
借用的。不过我不知道该怎么解决。到目前为止,我所有增加明确寿命的尝试都没有奏效。
问题在于:
impl<T> GetData<T> for &Base<T> {
fn get_data(&self) -> &T {
&self.data
}
}
老实说,我不知道你为什么只为&Base
而不是为Base
实现。但这就是问题的原因,因为Base的寿命和self的寿命不相同,并且您的self
是&&Base<T>
。
这意味着:
fn get_data(&self) -> &T {
(&self.base).get_data() // E0515: returns a value referencing data owned by the current function
//&self.base.data // This works fine!
}
结果的寿命是&self.base
的寿命,而不是self
的预期寿命。
如果你
impl<T> GetData<T> for Base<T> {
fn get_data(&self) -> &T {
&self.data
}
}
然后一切都会开箱即用。
我忍不住觉得整个事情都有OO思想的味道,GetData
特性有Java/C#接口的味道。