【发布时间】:2023-01-08 06:21:10
【问题描述】:
我有一个将切片分成三部分的函数,前导切片和尾随切片,以及对中间元素的引用。
/// The leading and trailing parts of a slice.
struct LeadingTrailing<'a, T>(&'a mut [T], &'a mut [T]);
/// Divides one mutable slice into three parts, a leading and trailing slice,
/// and a reference to the middle element.
pub fn split_at_rest_mut<T>(x: &mut [T], index: usize) -> (&mut T, LeadingTrailing<T>) {
debug_assert!(index < x.len());
let (leading, trailing) = x.split_at_mut(index);
let (val, trailing) = trailing.split_first_mut().unwrap();
(val, LeadingTrailing(leading, trailing))
}
我想为 LeadingTrailing<'a, T> 实现迭代器,以便它首先迭代第一个切片,然后迭代第二个切片。即,它的行为类似于:
let mut foo = [0,1,2,3,4,5];
let (item, lt) = split_at_rest_mut(&foo, 2);
for num in lt.0 {
...
}
for num in lt.1 {
...
}
我试过转换成Chain:
struct LeadingTrailing<'a, T>(&'a mut [T], &'a mut [T]);
impl <'a, T> LeadingTrailing<'a, T> {
fn to_chain(&mut self) -> std::iter::Chain<&'a mut [T], &'a mut [T]> {
self.0.iter_mut().chain(self.1.iter_mut())
}
}
但我得到错误:
89 | self.0.iter_mut().chain(self.1.iter_mut())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&mut [T]`, found struct `std::slice::IterMut`
我也试过创建一个自定义的Iterator
/// The leading and trailing parts of a slice.
struct LeadingTrailing<'a, T>(&'a mut [T], &'a mut [T]);
struct LTOthersIterator<'a, T> {
data: LeadingTrailing<'a, T>,
index: usize,
}
/// Iterates over the first slice, then the second slice.
impl<'a, T> Iterator for LTOthersIterator<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
let leading_len = self.data.0.len();
let trailing_len = self.data.1.len();
let total_len = leading_len + trailing_len;
match self.index {
0..=leading_len => {
self.index += 1;
self.data.0.get(self.index - 1)
}
leading_len..=total_len => {
self.index += 1;
self.data.1.get(self.index - leading_len - 1)
}
}
}
}
但我得到错误:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src\main.rs:104:29
|
104 | self.data.0.get(self.index - 1)
^^^
这样做的正确方法是什么?
【问题讨论】:
-
关于最后一次尝试,在可变数据上实现迭代器可能需要
unsafe,因为对它们的排他性限制:How can I create my own data structure with an iterator that returns mutable references? 话虽这么说,因为你只返回不可变引用,你应该在将它们存储在迭代器之前降级它们,然后你不会有那个问题。