Different types of string.chars(), for .next() and .peek()

Viewed 95

I'm trying to use string.chars().peekable() and the problem I have is that I have different types from .next() and .peek(). One is Option<char>, second is Option<&char>, and I have trouble to compare them.

My code is (s is String):

    let mut left_iter = s.chars().peekable();
    let mut right_iter = s.chars().rev().peekable();
    loop {
        let left = left_iter.next();
        let right = right_iter.next();
        let left_next = left_iter.peek();
        let left_right = right_iter.peek();
        if left == right || left == right_next {
          ...
        }

The error I get is obvious:

expected &char, found char

But I can't find a way to have both next() and peek() having the same type without re/deconstructing Option.

Is there a clean way to have both return values having the same type?

1 Answers

You have two options derefenccing (&T -> T) one or referencing (T -> &T) the other:

Dereferencing

Since they are wrapped in Option, you could zip them and operate over with map, pattern match or dereference the referenced one, otherwise return false.:

fn main() {
    let left = Some('c');
    let right = Some(&'c');
    println!("{}", right.zip(left).map(|(&r, l)| r == l).unwrap_or(false));
}

Playground

Or since char is Copy, you could use Option::copied:

fn main() {
    let left = Some('c');
    let right = Some(&'c');
    println!("{}", left == right.copied());
}

Referencing

Also, and maybe simpler, you could use as_ref to get an Option<&T> from an Option<T>:

fn main() {
    let left = Some('c');
    let right = Some(&'c');
    println!("{}", left.as_ref() == right);
}

Playground

Related