【发布时间】:2021-12-31 14:57:32
【问题描述】:
我目前正在尝试在缓冲区中实现一个可变切片/视图,该缓冲区支持安全地获取子切片以进行内存中消息遍历。一个最小的例子是
struct MutView<'s> {
data: &'s mut [u8]
}
impl<'s> MutView<'s> {
pub fn new(data: &'s mut [u8]) -> Self {
MutView { data }
}
pub fn subview<'a>(&'a mut self, start: usize, end: usize) -> MutView<'a> {
MutView::new(&mut self.data[start..end])
}
pub fn get<'a>(&'a mut self) -> &'a mut [u8] {
self.data
}
}
但是这种设计存在一个问题,如果我有一个在函数中本地创建的 MutView<'s> 并且 's 比函数的范围长(比如 's = 'static),我有无法从函数返回子视图。类似的东西
fn get_subview(data: &'s mut [u8]) -> MutView<'s> {
MutView::new(data).subview(0, 5)
}
由于MutView::new(data) 是一个本地临时变量,因此出现编译错误,因此很明显subview() 返回的MutView<'a> 无法从函数中返回。
将subview()的签名改为
pub fn subview<'a>(&'a mut self, start: usize, end: usize) -> MutView<'s> {
MutView::new(&mut self.data[start..end])
}
不可能,因为借用检查器抱怨返回对象的生命周期必须长于 &'a mut self 的生命周期。
我看到的问题是借用检查器被设置为处理 subview() 返回由 &'a mut self 拥有的数据的情况,而在这种情况下,我返回的数据属于某个底层缓冲区拥有的寿命超过生命周期的数据'a ,因此出于安全原因,我仍然希望在返回对象的生命周期内对&'a mut self 进行可变借用,同时还允许在不缩短返回子视图生命周期的情况下删除&'a mut self。
我看到的唯一选择是添加一个消耗 self.但是,对于我的具体情况,我正在生成 get_/set_ 方法来读取具有给定模式的消息,这意味着我在消息正文中的每个字段都有 get/set 方法,并且添加额外的 into_* 方法意味着要生成/编译大量额外代码,以及额外的使用复杂性。因此,如果可能的话,我想避免这种情况。
目前在 Rust 中是否有处理这种依赖的好方法?
【问题讨论】:
-
抱歉,应该是 MutView 并且已经修复。
-
我希望
subview()的正确签名是pub fn subview(&mut self, start: usize, end: usize) -> MutView<'s>(因为它返回一个新的MutView,它引用旧的数据) - 但doesn't compile 要么.我怀疑这个问题与使用生命周期不变的&mut引用有关。修改后的代码compiles 共享引用。
标签: rust borrow-checker