简体   繁体   English

如何在结构的所有生命周期中实现特征?

[英]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 .现在, SE类型的枚举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.第一个选项是让枚举RE中使用'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.

相关问题 如何统一结构和特征之间的寿命? - How can I unify the lifetimes between a struct and a trait? 如何为结构体的引用实现 Add trait? - How do I implement the Add trait for a reference to a struct? 如何为我的结构实现 FromIterator 特征? - How do I implement a FromIterator trait for my struct? 当特征要求的状态多于结构所包含的状态时,如何为该结构实现特征? - How do I implement a trait for a struct when the trait requires more state than is contained in the struct? 如何实现一个给生命周期结构的迭代器? - How to implement an iterator giving struct with lifetimes? 为什么作为参数传递的 trait 对象的生命周期需要更高的 Ranked Trait Bounds 而结构体不需要? - Why do the lifetimes on a trait object passed as an argument require Higher Ranked Trait Bounds but a struct doesn't? 我如何在结构中有一个特征字段? - How do I have a trait field in a struct? 如何为不同类型的参数实现一个结构的Fn特征? - How do I implement the Fn trait for one struct for different types of arguments? 如何级联实现结构的特征? - How to cascading implement Into trait for struct? 如何为包含Rc的结构实现Deref <Refcell<Trait> &gt;? - How can I implement Deref for a struct that holds an Rc<Refcell<Trait>>?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM