Get mutable reference from a vector

Hello guys, I’m learning Rust and I am doing some exercises to improve.
I wrote the following structure

pub struct A {
  key: Option<String>,
  value: Option<String>,
  children: Vec<A>,
}

I wrote the function that gives me the immutable reference of an element of the vector, but I cannot figure out how to write the function to retrieve the mutable reference of an element. I wrote the following function

pub fn get_mut_child(&mut self, key: String) -> Option<&mut A> {
	for child in &mut self.children {
		if let Some(ref child_key) = child.key {
			if *child_key == key {
				return Some(child);
			}
		}
	}

	None
}

I am borrowing the key variable from the element I want to return and I know that, since I want to return a mutable reference, I cannot do that. Am I missing something? Is there a way around this?

Thank you!

AFAIU this is a limitation of the current borrow checker, and it will be fixed soon with “non-lexical lifetimes” (but I’m not sure).

Borrow-checker can be tricked like this:

pub fn get_mut_child(&mut self, key: String) -> Option<&mut A> {
    for child in &mut self.children {
        let found = if let Some(ref child_key) = child.key {
	    *child_key == key
        } else {
	   false
	};
        if found {
            return Some(child);
        }
    }
    None
}

https://play.rust-lang.org/?gist=48ae0534831d413e5e47e6918bc7d3e7&version=stable&mode=debug&edition=2015

Ok thank you. So essentially the borrow checker doesn’t “understand” that in this case, child has the same lifetime has self? Is that the problem?
I would like to understand better :slight_smile:

I’m not an expert here. My naïve understanding is that you cannot do anything with mutable child while immutable child.key lives.

Immutable child.key borrow ends at the end of if expression (even if is not used after second if check), so you cannot do things with child until the end of outer if expression.

Oh right, I mean it makes sense even from the example you provided. Thank you very much.

Yes, NLL will help.

Check here

Can’t wait for NLL release.

A typical way to do this today on stable (ie without NLL) is by using position() followed by indexing: play

1 Like

Wow, this is really cool. Thank you!