[英]How do I implement a trait for all lifetimes of the struct?
I reduced my problem to this minimum reproducible example ( playground ):我将我的问题简化为这个最小的可重现示例( 操场):
use std::marker::PhantomData;
pub trait D<'a> {
type A: A + 'a;
type B: B + 'a;
}
pub trait A {
fn a(self);
}
pub trait B {
fn b(self);
}
pub struct AA {}
impl A for AA {
fn a() {}
}
pub struct BB<'a> {
phantom: PhantomData<&'a u8>,
}
impl<'a> B for BB<'a> {
fn b() {}
}
impl<'a: 'd, 'd> D<'d> for E<'a> {
type A = AA;
type B = BB<'a>;
}
#[derive(Clone)]
pub struct E<'a> {
phantom: PhantomData<&'a u8>,
}
pub struct S<D_T>
where
D_T: for<'d> D<'d>,
{
a: D_T,
}
pub enum R<'a> {
RR(S<E<'a>>),
}
I'm getting我越来越
error: implementation of `D` is not general enough
--> src/lib.rs:48:8
|
3 | / pub trait D<'a> {
4 | | type A: A + 'a;
5 | | type B: B + 'a;
6 | | }
| |_- trait `D` defined here
...
48 | RR(S<E<'a>>),
| ^^^^^^^^ implementation of `D` is not general enough
|
= note: `D<'0>` would have to be implemented for the type `E<'a>`, for any lifetime `'0`...
= note: ...but `D<'_>` is actually implemented for the type `E<'1>`, for some specific lifetime `'1`
I have a small idea why it's happening, but is there a way to have BB
with a reference in this case?我有一个小想法,为什么会这样,但在这种情况下,有没有办法让
BB
参考? Most of the things here are from a library I don't control so I cannot change them.这里的大部分内容都来自我无法控制的库,因此我无法更改它们。
The struct S
would need D
to be implemented for D_T
for all lifetimes, which would also include 'static
.结构
S
需要在所有生命周期中为D_T
实现D
,其中还包括'static
。 Now, S
is used in enum R
with type E
, with a generic lifetime 'a
.现在,
S
在E
类型的枚举R
中使用,具有通用生命周期'a
。 If 'a
is anything but 'static
, type B
of struct D
could not possibly be implemented containing a non-static reference.如果
'a
不是'static
,则 struct D
的类型B
不可能实现包含非静态引用。 This simply can not work, and something needs changing.这根本行不通,需要改变一些东西。
The first option would be to make enum R
use 'static
lifetime in E
, but that would be rather unpractical.第一个选项是让枚举
R
在E
中使用'static
生命周期,但这很不切实际。
Another option would be to remove the D_T: for<'d> D<'d>
requirement from S
, adding an additional lifetime argument, and adding phantom data to the structure.另一种选择是从
S
中删除D_T: for<'d> D<'d>
要求,添加一个额外的生命周期参数,并将幻像数据添加到结构中。
If neither of them are possible, and I am not missing anything, there is not much you can do without resorting to runtime checks, and making the BB
type not be lifetime bound (using reference counting).如果它们都不可能,并且我没有遗漏任何东西,那么如果不求助于运行时检查,并且使
BB
类型不受生命周期约束(使用引用计数),您将无能为力。 You would need to use either Rc<BB>
as B
, or have a Rc<SomeType>
inside the BB
.您需要使用
Rc<BB>
作为B
,或者在BB
中有一个Rc<SomeType>
。 The former would look something like this:前者看起来像这样:
impl<'d> D<'d> for E {
type A = AA;
type B = Rc<BB>;
}
#[derive(Clone)]
pub struct E {
ref_counted: Rc<BB>
}
pub struct BB {
}
impl B for Rc<BB> {
fn b(mut self) {
if let Some(bb) = Rc::get_mut(&mut self) {
//code with BB's MUTABLE REFERENCE
}
}
}
pub struct S<D_T>
where
D_T: for<'d> D<'d>,
{
a: D_T
}
pub enum R {
RR(S<E>),
}
The B
implementation uses a mutable reference of the underlying value in the method, if you would like to consume the value inside ref_counted
instead, you would have to try something like this: B
实现在方法中使用底层值的可变引用,如果您想使用ref_counted
中的值,则必须尝试以下操作:
impl B for Rc<BB> {
fn b(mut self) {
match Rc::try_unwrap(self) {
Ok(bb) => {
//code with BB's VALUE
},
Err(bbrc) => {
//we can not consume the value in self, because
//there was a reference held somewhere else in the code
//here lies code with BB's reference counted pointer
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.