如果你这样做该死,如果你不这样做该死:Rust编译器会抱怨,无论是否有生命周期参数

我正在尝试决定是否应该在我的 impls 中添加一个生命周期参数,但似乎我处于“如果你这样做该死,如果你不这样做该死”的情况,因为无论是否有一个生命周期参数,编译器都会抱怨.

pub struct TurtleRef<'a> {
    t: &'a BorrowedTurtle<'a>,
}

impl TurtleRef<'_> {
    pub fn borrowed_turtle(&self) -> BorrowedTurtle {
        *self.t
    }

    pub fn new(r: Turtle) -> TurtleRef {
        TurtleRef{t: &BorrowedTurtle{ t:r}}
    }
}

pub struct BorrowedTurtle<'a> {
    t: Turtle<'a>,
}

impl<'a> std::ops::Deref for BorrowedTurtle<'_> {
    type Target = Turtle<'a>;

    fn deref(&self) -> &Self::Target {
        &self.t
    }
}

impl<'a> std::ops::DerefMut for BorrowedTurtle<'_> {
    type Target = Turtle<'a>;
    fn deref_mut(&mut self) -> &mut Self::Target {
        &self.t
    }
}

pub struct Turtle<'a> {
    children: Vec<Turtle<'a>>,
}

Turtle 有更多的字段,但为了简单起见,我删除了它们。您可以在此处查看代码片段。代码抛出错误

error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
  --> src/campus.rs:54:6
   |
54 | impl<'a> std::ops::Deref for BorrowedTurtle<'_> {
   |      ^^ unconstrained lifetime parameter
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
  --> src/campus.rs:54:6
   |
54 | impl<'a> std::ops::Deref for BorrowedTurtle<'_> {
   |      ^^ unconstrained lifetime parameter

没问题,我会删除参数,因为它会引起如此大惊小怪。但是在删除它之后,我得到了一大堆新错误:


error[E0261]: use of undeclared lifetime name `'a`
  --> src/campus.rs:55:26
   |
55 |     type Target = Turtle<'a>;
   |                          ^^ undeclared lifetime
   |
help: consider introducing lifetime `'a` here
   |
54 | impl<'a> std::ops::Deref for BorrowedTurtle<'_> {
   |     ^^^^
help: consider introducing lifetime `'a` here
   |
55 |     type Target<'a> = Turtle<'a>;
   |                ^^^^

无论你说什么,我都会继续将该参数添加到目标。但现在我又收到另一个错误:

error[E0658]: generic associated types are unstable
  --> src/campus.rs:55:5
   |
55 |     type Target<'a> = Turtle<'a>;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information

所以无论我做什么,似乎我都遇到了一个重大错误。如何在不从头开始的情况下停止这些错误?我想保留 impls、structs 和 deref 函数,所以我唯一应该改变的是它们的实现。

另一方面,我收到错误

error[E0437]: type `Target` is not a member of trait `std::ops::DerefMut`
  --> src/campus.rs:64:5
   |
64 |     type Target = Turtle<'a>;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `std::ops::DerefMut`

因为 Turtle 没有实现 DerefMut,实际上 Turtle 不应该实现 DerefMut。是否对 Turtle 进行了轻微的修改,导致已经实现了 DerefMut 的东西?

回答

这里有几个问题。首先:

您要么使用匿名生命周期,要么不使用。在这里,您声明了'a,因此请使用它:

impl<'a> std::ops::Deref for BorrowedTurtle<'a> {

要使用省略的生命周期,您不必声明它:

impl std::ops::Deref for BorrowedTurtle<'_> {

但是,这里必须引用 中的生命周期Target,因此不能省略它。

第二:

error[E0437]: type `Target` is not a member of trait `std::ops::DerefMut`
  --> src/lib.rs:28:5
   |
28 |     type Target = Turtle<'a>;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `std::ops::DerefMut`

DerefMut没有Target成员,因为它重用了它的超特征Deref. 这是为了确保项目必须DerefDerefMut相同Target

impl<'a> std::ops::Deref for BorrowedTurtle<'a> {
    type Target = Turtle<'a>;

    fn deref(&self) -> &Self::Target {
        &self.t
    }
}

impl std::ops::DerefMut for BorrowedTurtle<'_> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.t
    }
}

最后,您现在将收到'a未使用的错误:

error[E0392]: parameter `'a` is never used
  --> src/lib.rs:15:27
   |
15 | pub struct BorrowedTurtle<'a> {
   |                           ^^ unused parameter
   |
   = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`

这是因为您有几个递归类型,其中生命周期实际上没有被使用:

// 'a isn't actually used for anything

pub struct Turtle<'a> {
    children: Vec<Turtle<'a>>,
}

pub struct BorrowedTurtle<'a> {
    t: Turtle<'a>,
}

我将假设出于此答案的目的,您省略了使用 的其他相关字段,仅此而已'a


以上是如果你这样做该死,如果你不这样做该死:Rust编译器会抱怨,无论是否有生命周期参数的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>