[英]Traits, returning a reference to an owned field via a trait method that returns `Self::Item`
Returning a reference to an owned field is allowed in other scenarios.在其他情况下允许返回对拥有字段的引用。 For instance, the code below compiles fine.
例如,下面的代码编译得很好。
struct Charlie<T> {
delta: T,
}
impl<T> Charlie<T> {
fn delta(&self) -> &T
{
&self.delta
}
}
I'd like to return a reference to an owned field from a trait method in similar fashion.我想以类似的方式从 trait 方法返回对拥有字段的引用。 Assume that
Alpha
is a trait in the standard library, so I can't modify it.假设
Alpha
是标准库中的一个特征,所以我不能修改它。
Is there a way to implement this?有没有办法实现这个?
trait Alpha {
type Item;
fn bravo(&mut self) -> Self::Item;
}
impl<T> Alpha for Charlie<T> {
type Item = &T;
fn bravo(&mut self) -> Self::Item
{
&self.delta
}
}
The above doesn't compile and the error messages don't seem to apply.以上内容无法编译,并且错误消息似乎不适用。 If I try following the error message suggestions, things just get complicated and I run into a series of errors with suggestions that also don't pan out.
如果我尝试遵循错误消息建议,事情就会变得复杂,并且我会遇到一系列错误,并且建议也不会成功。
Compiling playground v0.0.1 (/playground)
error[E0106]: missing lifetime specifier
--> src/main.rs:22:17
|
22 | type Item = &T;
| ^ expected named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
22 | type Item<'a> = &'a T;
| ^^^^ ^^^
I've tried the above suggestion and went so far as to declare 'a
on Charlie
's struct and add a PhantomData
field, and thoroughly peppered the rest of my sources with 'a
s.我已经尝试了上述建议,甚至在
Charlie
的结构上声明'a
并添加一个PhantomData
字段,并用'a
s. And the compiler continues whining and complaining and nagging throughout the whole process.编译器在整个过程中不断地抱怨、抱怨和唠叨。
I managed to find this post on StackOverflow , but the solutions there seem to all require modifying the trait.我设法在 StackOverflow 上找到了这篇文章,但那里的解决方案似乎都需要修改特征。
I'm thinking what I'm trying to do may not be possible.我在想我想做的事情可能是不可能的。 But I don't really understand why not.
但我真的不明白为什么不。
The Alpha
trait method that I was struggling with is actually我一直在努力的
Alpha
trait 方法实际上是
type Item = Take<&I>;
fn next(&mut self) -> Option<Self::Item> { ... }
I was trying to return another wrapped iterator type, where I
is the wrapped iterator.我试图返回另一个包装的迭代器类型,
I
是包装的迭代器。 The Iterator
trait itself doesn't define any lifetimes I can leverage. Iterator
trait 本身并没有定义我可以利用的任何生命周期。
I do know a way to implement around this limitation using the smart pointer classes to encapsulate the field I want to share in Charlie
.我确实知道一种解决此限制的方法,使用智能指针类来封装我想在
Charlie
中共享的字段。 Then make that my Item
type.然后将其设为我的
Item
类型。 I was just hoping for something with less overhead.我只是希望开销更少的东西。
The contract for that trait unfortunately doesn't allow it.不幸的是,该特征的合同不允许这样做。
trait Alpha {
type Item;
fn bravo(&mut self) -> Self::Item;
}
This says that, if Self
is an Alpha
, then "there exists some single Self::Item
which I can get from any &mut self
with any lifetime".这就是说,如果
Self
是Alpha
,那么“存在一些单一的Self::Item
,我可以在任何生命周期内从任何&mut self
获得”。 You want "there exists a class of Self::Item
whose lifetimes relate to &mut self
in a nontrivial way".您想要“存在一个
Self::Item
的 class ,其生命周期与&mut self
以一种重要的方式相关”。
The easiest way to get around this is to make bravo
take self
by value.解决这个问题的最简单方法是让
bravo
重视self
。
trait Alpha {
type Item;
fn bravo(self) -> Self::Item;
}
Now, the contract says "there's some way to get a Self::Item
from a self
", which is much simpler.现在,合同说“有一些方法可以从一个
self
中获取一个Self::Item
”,这要简单得多。 We can implement it as我们可以将其实现为
impl<'a, T> Alpha for Charlie<&'a mut T> {
type Item = &'a T;
fn bravo(self) -> Self::Item {
&self.delta
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.