我定义了以下特征:
trait Read<T> {
fn next_row<'c>(&'c mut self) -> Result<std::option::Option<T>>;
}
(显然
'c
会被省略,但我只是想以后能够参考它)
我已经为结构体
ReaderA
实现了这个,以返回拥有的值:
struct ReaderA {
data: Vec<Vec<u8>>
}
impl Read<Vec<u8>> for ReaderA {
fn next_row<'c>(&'c mut self) -> Result<std::option::Option<Vec<u8>>> {
Ok(self.data.pop())
}
}
毫不奇怪,这非常有效。当我尝试为某些结构实现此方法以返回借用的值时,就会出现问题:
ReaderB
这行不通。签名与定义不匹配,因为该特征不希望
struct ReaderB {
data: Vec<Vec<u8>>
}
impl Read<&Vec<u8>> for ReaderB {
fn next_row<'c>(&'c mut self) -> Result<std::option::Option<&'c Vec<u8>>> {
Ok(self.data.first())
}
}
包含在返回值中。我做错了什么?
我可以将生命周期添加为特征通用参数,但这感觉没有必要:我不想指定其他生命周期,我只是希望它共享'c
借用的生命周期(我认为)。我也宁愿不必在每个特征的实现中包含生命周期,并在每个结构中包含
&mut self
,即使它们不返回借用的值。我也不想遇到像this这样的事情,但我真的不明白我在做什么。 我觉得这可能与 HRTB 有关,但我不知道如何让它发挥作用。
我有点迷失了一生,所以请在你的答案中包含尽可能多的细节。
不鼓励使用泛型作为返回值,除非您正在实现一个转换函数或类似的函数,您的特征的用户想要决定它应该是什么类型。如果每个实现类型只有一个返回类型,请改用
PhantomData
。特征定义没有捕获
std::iter::Iterator
T
。在一种情况下确实如此,在另一种情况下则不然。这是你的方法失败的主要问题;如果有人想使用该特征,他可以保留生成的值,但销毁 Self
对象,这应该说明为什么示例代码中的 Read
实现被正确禁止。
ReaderB
应始终比返回值更长寿,那么它就可以工作:
Self