Create iterator function in std libs: split_item_mut()

When I started with rust I had a lot of difficulties iterating over a vector that I had already borrowed mutably. I fixed it back then with swap_remove or index based looping and mutating the vector spot immediately. Which I find both to be hacky. However I created the following trait which I think is much more user friendly for especially new users.

pub type OtherIterMut<'a, T> = std::iter::Chain<IterMut<'a, T>, IterMut<'a, T>>;

pub trait Splitting<T: std::fmt::Debug> {
    fn split_item_mut(&mut self, idx: usize) -> (&mut T, OtherIterMut<T>);
}

impl<T: std::fmt::Debug> Splitting<T> for Vec<T> {
    fn split_item_mut(&mut self, idx: usize) -> (&mut T, OtherIterMut<T>) {
        assert!(idx < self.len());

        let (head, rest) = self.split_at_mut(idx);

        let (item, tail) = rest.split_first_mut().unwrap();

        let others = head.iter_mut().chain(tail.iter_mut());

        (item, others)
    }
}

In this way I can use:

let (item, others) = some_vector.split_item_mut(some_index);
for other in others {
     other.some_field = item.some_field;
}

Of course the API can change a bit to make it index safe with Option, and maybe with different types of mutability settings. But I think this is something a lot of users can benefit from.

I think that if this were to be in core, it'd look more like -> (&mut [T], &mut T, &mut [T]).

People can always chain the before-and-after later if they want, but recovering the slices from a Chain is not possible today.

If you'd like to turn this into an official proposal to libs-api, see Feature lifecycle - Standard library developers Guide.

6 Likes

Ok thanks for the feedback, related Github issue: Create iterator function in std libs: split_item_mut() · Issue #295 · rust-lang/libs-team · GitHub

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.