【问题标题】:conflicting lifetime requirements on implementing Clone for simple struct为简单结构实现克隆的生命周期要求冲突
【发布时间】:2021-06-29 07:30:16
【问题描述】:

我正在设计一个简单的类型来保存Vec<u8> 或切片(mut 或 not mut)。我在生命周期限制方面遇到问题,这次我不知道为什么会有冲突的要求:

use std::vec::Vec;

pub enum EncodedPacket<'a> {
    Owned(Vec<u8>),
    Ref(&'a [u8]),
    RefMut(&'a mut [u8])
}

impl<'a> EncodedPacket<'a> {
    pub fn new_ref(slice: &'a [u8]) -> EncodedPacket<'a> {
        EncodedPacket::Ref(slice)
    }

    pub fn new_ref_mut(slice: &'a mut [u8]) -> EncodedPacket<'a> {
        EncodedPacket::RefMut(slice)
    }

    pub fn new_owned(vec: Vec<u8>) -> EncodedPacket<'a> {
        EncodedPacket::Owned(vec)
    }
}

impl<'a> Clone for EncodedPacket<'a> {
    fn clone(&self) -> Self {
        match self {
            EncodedPacket::Owned(vec)=> EncodedPacket::new_owned(*vec),
            EncodedPacket::Ref(slice) => EncodedPacket::new_ref(*slice),
            EncodedPacket::RefMut(slice) => EncodedPacket::new_ref_mut(*slice)
        }
    }
}

Playground

错误:

  Compiling playground v0.0.1 (/playground)
error[E0495]: cannot infer an appropriate lifetime for pattern due to conflicting requirements
  --> src/lib.rs:28:35
   |
28 |             EncodedPacket::RefMut(slice) => EncodedPacket::new_ref_mut(*slice)
   |                                   ^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 24:14...
  --> src/lib.rs:24:14
   |
24 |     fn clone(&self) -> Self {
   |              ^^^^^
note: ...so that reference does not outlive borrowed content
  --> src/lib.rs:28:35
   |
28 |             EncodedPacket::RefMut(slice) => EncodedPacket::new_ref_mut(*slice)
   |                                   ^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 23:6...
  --> src/lib.rs:23:6
   |
23 | impl<'a> Clone for EncodedPacket<'a> {
   |      ^^
note: ...so that the expression is assignable
  --> src/lib.rs:25:9
   |
25 | /         match self {
26 | |             EncodedPacket::Owned(vec)=> EncodedPacket::new_owned(*vec),
27 | |             EncodedPacket::Ref(slice) => EncodedPacket::new_ref(*slice),
28 | |             EncodedPacket::RefMut(slice) => EncodedPacket::new_ref_mut(*slice)
29 | |         }
   | |_________^
   = note: expected `EncodedPacket<'a>`
              found `EncodedPacket<'_>`

我只是用相同的内部事物重新创建EncodedPacket,我根本不明白为什么存在冲突的生命周期要求。

【问题讨论】:

  • 您无法克隆&amp;mut,因此我认为您必须为此使用某种智能指针。 Rc, Rc&lt;RefCell&gt;
  • 除此错误外,您还尝试克隆一个可变引用,除非您对它进行一些魔术,否则最终将无法正常工作

标签: rust


【解决方案1】:

您不能克隆可变引用。一种方法是将其包装在 RcRc&lt;RefCell&gt; 中:

use std::vec::Vec;
use std::cell::RefCell;
use std::rc::Rc;

#[derive(Clone)]
pub enum EncodedPacket<'a> {
    Owned(Vec<u8>),
    Ref(Rc<&'a [u8]>),
    RefMut(Rc<RefCell<&'a mut [u8]>>)
}

impl<'a> EncodedPacket<'a> {
    pub fn new_ref(slice: &'a [u8]) -> EncodedPacket<'a> {
        EncodedPacket::Ref(Rc::new(slice))
    }

    pub fn new_ref_mut(slice: &'a mut [u8]) -> EncodedPacket<'a> {
        EncodedPacket::RefMut(Rc::new(RefCell::new(slice)))
    }

    pub fn new_owned(vec: Vec<u8>) -> EncodedPacket<'a> {
        EncodedPacket::Owned(vec)
    }
}

Playground

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2017-09-28
  • 1970-01-01
  • 2015-04-30
  • 2019-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-26
相关资源
最近更新 更多