Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
977 views
in Technique[技术] by (71.8m points)

rust - How do I call Peekable::next based on the result of Peekable::peek?

use std::iter::Peekable;

pub trait AdvanceWhile<I: Iterator> {
    fn advance_while<P>(&mut self, predicate: P)
    where
        P: Fn(&I::Item) -> bool;
}

impl<I: Iterator> AdvanceWhile<I> for Peekable<I> {
    fn advance_while<P>(&mut self, predicate: P)
    where
        P: Fn(&I::Item) -> bool,
    {
        while let Some(val) = self.peek() {
            if predicate(val) {
                self.next();
            } else {
                break;
            }
        }
    }
}

Playground

Error:

error[E0499]: cannot borrow `*self` as mutable more than once at a time
  --> src/main.rs:16:17
   |
14 |         while let Some(val) = self.peek() {
   |                               ---- first mutable borrow occurs here
15 |             if predicate(val) {
16 |                 self.next();
   |                 ^^^^ second mutable borrow occurs here
...
20 |         }
   |         - first borrow ends here
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Typical case of lexical borrowing: the compiler is not yet able to understand that this is code is safe. So for the time being (until the so called non-lexical borrowing is implemented), try to rewrite your code. Like this, for example:

fn advance_while<P>(&mut self, predicate: P)
    where P: Fn(&I::Item) -> bool 
{
    loop {
        if let Some(val) = self.peek() {
            if !predicate(val) {
                break;
            }
        } else {
            break;
        }
        self.next();
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...