如果你这样做该死,如果你不这样做该死: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. 这是为了确保项目必须Deref和DerefMut相同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!
THE END
二维码