rust - Traits,通过返回 `Self::Item` 的 trait 方法返回对拥有字段的引用
问题描述
在其他情况下允许返回对拥有字段的引用。例如,下面的代码编译得很好。
struct Charlie<T> {
delta: T,
}
impl<T> Charlie<T> {
fn delta(&self) -> &T
{
&self.delta
}
}
我想以类似的方式从 trait 方法返回对拥有字段的引用。假设这Alpha
是标准库中的一个特征,所以我不能修改它。
有没有办法实现这个?
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
}
}
以上内容无法编译,并且错误消息似乎不适用。如果我尝试遵循错误消息建议,事情就会变得复杂,并且我会遇到一系列错误,并且建议也不会成功。
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;
| ^^^^ ^^^
我已经尝试了上述建议,甚至'a
在Charlie
struct 上声明并添加了一个PhantomData
字段,并用 s 彻底填充了我的其余来源'a
。编译器在整个过程中不断地抱怨、抱怨和唠叨。
我设法在 StackOverflow 上找到了这篇文章,但那里的解决方案似乎都需要修改特征。
我在想我想做的事情可能是不可能的。但我真的不明白为什么不。
我一直在努力的Alpha
特质方法实际上是
type Item = Take<&I>;
fn next(&mut self) -> Option<Self::Item> { ... }
我试图返回另一个包装的迭代器类型,I
包装的迭代器在哪里。Iterator
特质本身并没有定义我可以利用的任何生命周期。
我确实知道一种解决此限制的方法,使用智能指针类来封装我想要共享的字段Charlie
。然后让它成为我的Item
类型。我只是希望开销更少的东西。
解决方案
不幸的是,该特征的合同不允许这样做。
trait Alpha {
type Item;
fn bravo(&mut self) -> Self::Item;
}
这就是说,如果Self
是一个Alpha
,那么“存在一些Self::Item
我可以从任何 一生&mut self
中得到的单曲”。你想要“存在一个类,Self::Item
其生命周期以&mut self
非平凡的方式相关”。
解决这个问题的最简单方法是按价值bravo
取值self
。
trait Alpha {
type Item;
fn bravo(self) -> Self::Item;
}
现在,合同说“有一些方法可以Self::Item
从 a 中获取 a self
”,这要简单得多。我们可以将其实现为
impl<'a, T> Alpha for Charlie<&'a mut T> {
type Item = &'a T;
fn bravo(self) -> Self::Item {
&self.delta
}
}
推荐阅读
- javascript - ECMAScript AssignmentExpression 生产规则如何产生`foo = 42`?
- python-3.x - 我知道这可以使用 and 运算符来完成,但我想用 if else 语句来做到这一点
- c# - 在 Azure 订阅中部署 Azure 持久功能错误
- java - 通过网页显示 Swing 应用程序窗口
- ios - 如何在 Swift 的 web 视图中运行 javascript
- html - 标签“img”只能作为标签“noscript”的后代出现。您指的是 'amp-img' 吗?
- node.js - 从流中播放音频
- javascript - 将类部署为 Firebase 云函数的正确方法是什么?
- java - 在繁重的 OpenCV 操作后正确清理内存
- c++ - 如何解释这个,右边的变量“i”会首先被评估吗?