与特质相关的类型生命周期和自我
我有一个结构,该结构包装了 std :: Cell :: Ref
,并通过参考基础值提供访问。这样的事情:
use std::cell::Ref;
struct IntAccess<'a> {
i: Ref<'a, i32>,
}
impl IntAccess<'_> {
fn get(&self) -> &i32 {
&self.i
}
}
这可以正常工作。由于我有这样的多个结构,因此我想定义一个常见的特征:
trait Access {
type Item;
fn get(&self) -> Self::Item;
}
但是,我在尝试实现 access
for intaccess
时会遇到麻烦:
impl<'a> Access for IntAccess<'a> {
type Item = &'a i32;
fn get(&self) -> Self::Item {
&self.i
}
}
它会失败以下错误:
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> src/main.rs:23:9
|
23 | &self.i
| ^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime defined here...
--> src/main.rs:22:12
|
22 | fn get(&self) -> Self::Item {
| ^^^^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:23:9
|
23 | &self.i
| ^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined here...
--> src/main.rs:19:6
|
19 | impl<'a> Access for IntAccess<'a> {
| ^^
note: ...so that the types are compatible
--> src/main.rs:22:33
|
22 | fn get(&self) -> Self::Item {
| _________________________________^
23 | | &self.i
24 | | }
| |_____^
= note: expected `<IntAccess<'a> as Access>`
found `<IntAccess<'_> as Access>`
我认为我有点会得到编译器试图告诉我的内容:我试图借用 self.i
,它与 self的寿命无关的匿名寿命:项目
('a
)。因此,似乎需要的是以某种方式将 self
in get
中的的寿命与寿命'a
联系起来。有办法这样做吗?
我必须承认,我没有完全掌握这个问题。由于我将lifetime 'a
传递给 ref
,并且 ref
内部存储此寿命的参考,在我看来,它应该以某种方式可以从中获得使用Lifetime 的参考,而无需将 self
也与此生命周期明确联系。那我在这里想念什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的理解是正确的。关于您的疑问,让我们命名寿命以进行更轻松的调试:
self
具有类型&amp;'b intaccess&lt;'a&gt;
。'b
比'
-self
是 , IE可以存在(否则,它将包含一个悬空的参考)。因此,我们不能借用
self
超过'b
- 或我们可以做类似的事情:我们既有共享和可变的参考(一部分)
内部
!如果没有 self 的生命周期相关的相关类型”:
我们可以在稳定上这样做吗?我们可以模仿。我们将无需实现
访问
intaCcess
本身,而是为对其进行实施!nightly&amp;mode=debug&;工作,因此不能完全替代GAT,而是在这种情况下足够好。
Your understanding is correct. About your doubt, let's name the lifetimes for easier debugging:
self
has the type&'b IntAccess<'a>
.'b
is shorter than or equal to'a
- that is required forself
to be well-formed, i.e. able to exist (otherwise, it would contain a dangling reference).For that reason, we cannot borrow
self
for more than'b
- or we could do something like:And we have both a shared and a mutable reference to (parts of)
inner
!Your problem cannot be solved fully without Generic Associated Types. They allow you to parameterize an associated type by a lifetime, making it able to express "I want to return this associated type tied to the lifetime of
self
":Playground.
Can we do that on stable? We can emulate that. Instead of implementing
Access
forIntAccess
itself, we will implement it for a reference to it!Playground
This does not always work, and thus is not a full replacement to GATs, but is good enough in this case.