【问题标题】:Owned data is getting a lifetime拥有的数据将拥有一生
【发布时间】:2021-07-18 09:32:00
【问题描述】:

在下面的代码中,我正在尝试转换对拥有数据的引用。方法to_owned 确保新返回类型的'static 生命周期。但是,由于impl <'a>,它抱怨这个返回的类型并不是真正的'static。我看不出'a 与此有什么关系,因为to_owned 中的所有返回对象都是owned,因此应该是'static

pub enum RRtspEncodedPacket<'a> {
    Owned(Data<Body>),
    Ref(&'a Data<Body>)
}

pub struct Body(Inner);

enum Inner {
    Vec(Vec<u8>),
    Custom(Box<dyn Custom>),
}

trait Custom: AsRef<[u8]> + Send + Sync + 'static {}

pub struct Data<Body> {
    pub(crate) channel_id: u8,
    pub(crate) body: Body,
}

pub trait EncodedPacket<'a, T: Send>: Send {
    fn to_owned(&self) -> Box<dyn EncodedPacket<'static, T>>;
}

impl<'a> EncodedPacket<'a, u8> for RRtspEncodedPacket<'a> {
    fn to_owned(&self) -> Box<dyn EncodedPacket<'static, u8>> {
        match self {
            Self::Owned(o) => Box::new(Self::Owned(*o.clone())),
            Self::Ref(data) => Box::new(Self::Owned(*(*data).clone()))
        }
    }
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1eafce83690156b9df6432fd7092fec0

错误:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
  --> src/lib.rs:27:40
   |
27 |             Self::Owned(o) => Box::new(Self::Owned(*o.clone())),
   |                                        ^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 24:6...
  --> src/lib.rs:24:6
   |
24 | impl<'a> EncodedPacket<'a, u8> for RRtspEncodedPacket<'a> {
   |      ^^
note: ...so that the types are compatible
  --> src/lib.rs:27:40
   |
27 |             Self::Owned(o) => Box::new(Self::Owned(*o.clone())),
   |                                        ^^^^^^^^^^^
   = note: expected `RRtspEncodedPacket<'_>`
              found `RRtspEncodedPacket<'a>`
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the expression is assignable
  --> src/lib.rs:27:31
   |
27 |             Self::Owned(o) => Box::new(Self::Owned(*o.clone())),
   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: expected `Box<(dyn EncodedPacket<'static, u8> + 'static)>`
              found `Box<dyn EncodedPacket<'static, u8>>`

【问题讨论】:

    标签: rust


    【解决方案1】:

    to_owned() 中,您承诺会返回Box&lt;dyn EncodedPacket&lt;'static, u8&gt;&gt;。但是你使用Box&lt;RRtspEncodedPacket&lt;'a&gt;&gt; 来构造返回值; 'a 可能比'static 短,这是编译器所抱怨的。这可以通过在Box::new(Self::Owned(*o.clone())) 中使用Self 来促进。这里,Self 指的是impl 块的类型,所以SelfRRtspEncodedPacket&lt;'a&gt;;这就是'a 潜入返回类型的方式。但你想要的是RRtspEncodedPacket&lt;'static&gt;。只需将 Self 切换为 RRtspEncodedPacket - 编译器将推断为 RRtspEncodedPacket&lt;'static&gt; - 即可解决您的问题。

    编译的简化示例:

    pub enum RRtspEncodedPacket<'a> {
        Owned(u32),
        Ref(&'a u32)
    }
    
    pub trait EncodedPacket<'a, T> {
        fn to_owned(&self) -> Box<dyn EncodedPacket<'static, T>>;
    }
    
    impl<'a> EncodedPacket<'a, u8> for RRtspEncodedPacket<'a> {
        fn to_owned(&self) -> Box<dyn EncodedPacket<'static, u8>> {
    
            // Notice: No `Self`, because we go from whatever `Self` is
            // (some `RRtspEncodedPacket<'a>` for some `'a`) to
            // `RRtspEncodedPacket<'static>`.
            match self {
                Self::Owned(o) => Box::new(RRtspEncodedPacket::Owned(o.clone())),
                Self::Ref(data) => Box::new(RRtspEncodedPacket::Owned((*data).clone()))
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-01
      • 1970-01-01
      • 2013-03-14
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 2013-08-10
      相关资源
      最近更新 更多