该死的,如果你这样做,如果你不这样做,该死的:无论是否有生命周期参数,Rust 编译器都会抱怨
Damned if you do, damned if you don't: Rust compiler complains regardless whether there's a lifetime parameter or not
我正在尝试决定是否应该向我的 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 有更多字段,但为了简单起见,我删除了它们。您可以看到代码片段 here。代码抛出错误
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?
由于 DerefMut
继承自 Deref
,您不必指定 Target
,pub trait DerefMut: Deref {
使用 Target
在 [=14= 中定义] 实施。
Deref trait 非常特殊,它不能被“普通”用户真正使用,几乎只有 std 可以为新类型实现它。
这是因为它是借用自己和 return 引用“其他东西”问题是这个其他东西不能是临时的,例如标准使用它控制 rust 生态系统能够做到这一点Vec
实施:
impl<T, A: Allocator> ops::DerefMut for Vec<T, A> {
fn deref_mut(&mut self) -> &mut [T] {
unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) }
}
}
如您所见,slice 是一个“胖指针”,因此它只需要一个引用即可生效,您几乎可以只实现 Deref
到 return Target
对于像 slice
.
这样的类型
另一个例子是 PathBuf
:
impl ops::Deref for PathBuf {
type Target = Path;
#[inline]
fn deref(&self) -> &Path {
Path::new(&self.inner)
}
}
这里就更清楚了Path::new
创建一个胖指针。因此,Target 不能是不能自包含或已经存在于您的 Self
.
中的其他东西
正如 documentation 所说:
Because of this, Deref should only be implemented for smart pointers to avoid confusion.
我认为您真正想要的是实现 Borrow
。综上所述......这里是一个工作代码:
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
}
}
随心所欲
这里有几个问题。第一:
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
您要么使用匿名生命周期,要么不使用。在这里,你声明了'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
的相关字段,仅此而已!
我正在尝试决定是否应该向我的 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 有更多字段,但为了简单起见,我删除了它们。您可以看到代码片段 here。代码抛出错误
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?
由于 DerefMut
继承自 Deref
,您不必指定 Target
,pub trait DerefMut: Deref {
使用 Target
在 [=14= 中定义] 实施。
Deref trait 非常特殊,它不能被“普通”用户真正使用,几乎只有 std 可以为新类型实现它。
这是因为它是借用自己和 return 引用“其他东西”问题是这个其他东西不能是临时的,例如标准使用它控制 rust 生态系统能够做到这一点Vec
实施:
impl<T, A: Allocator> ops::DerefMut for Vec<T, A> {
fn deref_mut(&mut self) -> &mut [T] {
unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) }
}
}
如您所见,slice 是一个“胖指针”,因此它只需要一个引用即可生效,您几乎可以只实现 Deref
到 return Target
对于像 slice
.
另一个例子是 PathBuf
:
impl ops::Deref for PathBuf {
type Target = Path;
#[inline]
fn deref(&self) -> &Path {
Path::new(&self.inner)
}
}
这里就更清楚了Path::new
创建一个胖指针。因此,Target 不能是不能自包含或已经存在于您的 Self
.
正如 documentation 所说:
Because of this, Deref should only be implemented for smart pointers to avoid confusion.
我认为您真正想要的是实现 Borrow
。综上所述......这里是一个工作代码:
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
}
}
随心所欲
这里有几个问题。第一:
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
您要么使用匿名生命周期,要么不使用。在这里,你声明了'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
的相关字段,仅此而已!