rust - 为简单结构实现克隆的生命周期要求冲突
问题描述
我正在设计一个简单的类型来保存一个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)
}
}
}
错误:
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
用相同的内部事物重新创建,我不明白为什么会有冲突的生命周期要求。
解决方案
您不能克隆可变引用。这样做的一种方法是将其包装在Rc
and中Rc<RefCell>
:
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)
}
}
推荐阅读
- c# - System.ArgumentOutOfRangeException: '索引和长度必须引用字符串中的位置。在c#中
- c# - 为什么从 List 中删除最后一个元素的复杂性对于数组来说是 O(1) 和 O(n)?
- java - JAVA:如何解析日志文件直到找到特定的行,就像linux中的tail命令一样?
- c# - 如何在 C# 中创建一个毫秒的日期时间变量?(西装外套)
- youtube - Youtube 视频版本控制
- kubernetes - 从秘密映射时,Kubernetes pod 环境变量未更新
- db2 - 大型机:如何防止批处理作业和 CICS 事务之间的 DB2 争用?
- flutter - 使用Image.memory在flutter中加载base64图像时出现格式异常
- kubernetes - 问:Rancher + Calico + Ununtu 20.04 裸机 - 无法访问服务网络 (10.43.0.10)
- optimization - 快速评估决策森林