Getting “temporary value dropped while borrowed” when trying to update an Option<&str> in a loop

前端 未结 2 885
隐瞒了意图╮
隐瞒了意图╮ 2021-01-05 06:00

I\'m trying to implement a commonly used pattern - using the result of a previous loop iteration in the next loop iteration. For example, to implement pagination where you n

2条回答
  •  耶瑟儿~
    2021-01-05 06:51

    r.str.to_owned() is a temporary value. You can take a reference to a temporary, but because the temporary value will usually be dropped (destroyed) at the end of the innermost enclosing statement, the reference becomes dangling at that point. In this case the "innermost enclosing statement" is either the last line of the loop, or the loop body itself -- I'm not sure exactly which one applies here, but it doesn't matter, because either way, you're trying to make last contain a reference to a String that will soon be dropped, making last unusable. The compiler is right to stop you from using it again in the next iteration of the loop.

    The easiest fix is just to not make last a reference at all -- in the example, it's not necessary or desirable. Just use Option:

    fn main() {
        let times = 10;
        let mut last = None;
    
        for _ in 0..times {
            last = match do_something(last) {
                Some(r) => Some(r.str),
                None => None,
            };
        }
    }
    
    fn do_something(_: Option) -> Option {
        // ...
    }
    

    There are also ways to make the reference version work; here is one:

    let mut current;  // lift this declaration out of the loop so `current` will have
                      // a lifetime longer than one iteration
    for _ in 0..times {
        current = do_something(last);
        last = match current {
            Some(ref r) => Some(&r.str),  // borrow from `current` in the loop instead
                                          // of from a newly created String
            None => None,
        };
    }
    

    You might want to do this if your code is more complicated than the example and using String would mean a lot of potentially expensive .clone()s.

提交回复
热议问题