One simple way to iterate over a vector and preserve the right to push
onto it is to use something like a while loop instead:

    let mut i = 0;
    while i < vec.len() {
        process(vec[i]); // may alter vec
    }


It would be trivial to package this pattern up into a special iterator
that only works on `@mut` vectors and which iterated by value (not by
reference). Rust won't let you push while iterating by reference,
because pushing onto the vector may resize it and hence free the
memory.

Would this solve your problem?



Niko



On Mon, Aug 19, 2013 at 09:54:17PM -0700, Jeaye wrote:
> Howdy,
> 
> I've become a big fan of @mut throughout my codebase for its
> compatibility with closures, but I think it's really biting me in the
> ass right now. >.<
> 
> Assume there's a state stack (in a state Director) that I'm looping
> through to let the states know about an event. In this particular
> instance, the event is a key action of ENTER, since 'load_map q3ctf1'
> was just typed into the in-game console and ENTER was pressed. The
> console state is interested in this event, no doubt.
> 
> When the console state gets this load_map command, it'll spring off a
> function that creates a game and game_renderer, which are both states
> that need to be pushed onto the state stack. But wait! We're
> currently looping through the state stack, so trying to add something
> to it is an assertion failure on the borrow (BAM, hard failure).
> 
> In C++, this could would be perfectly valid, so long as I'm iterating
> through the state stack with indices and I'm pushing to the end of
> it, thus not affecting the current index. In Rust, this is a big
> no-no. My question is: how can I avoid this? Is it just because I'm
> using @mut that I'm having this problem? What are some potential
> solutions that people can think of, and has anyone hit the same snag
> in their own code?
> 
> Something I have tried: Adding a queue to the state Director of
> callback functions (deferred modifications to the states) that states
> will push closures onto instead of modifying the Director while it's
> looping. With this, the Director could loop through each state,
> updating it, and then loop through the queue of deferred callbacks
> and run them, which would update the states stack. This didn't work
> for me since the Director itself has the borrow lock on it, not just
> the states stack -- I reckon I could put the deferred queue into TLS
> so that I wouldn't need a mutable reference to the Director to add to
> it... but there has to be a better way.
> 
> Any tips would be appreciated.
> 
> Jeaye
> _______________________________________________
> Rust-dev mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to