I am interested in looking ahead into the flow of characters. As far as I understand, Peekable is the way to go. I can’t figure out how to use it.
First try:
fn trawl<I, E>(pk: &mut I) where I: std::iter::Peekable<Result<char, E>> { loop { let cur = pk.next(); let nxt = pk.peek(); match (cur, nxt) { (Some(i), Some(nxt_i)) => println!("{} {}", i.ok(), nxt_i.ok()), _ => (), } } } fn main() { trawl(&mut std::io::stdio::stdin().chars()); }
This does not compile with
> rustc /tmp/main.rs /tmp/main.rs:1:37: 1:73 error: `std::iter::Peekable` is not a trait /tmp/main.rs:1 fn trawl<I, E>(pk: &mut I) where I: std::iter::Peekable<Result<char, E>> { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error
Good, right. I don't fully understand the features yet, so I'm trying to pass an iterator and then create a peekable version:
fn trawl<I, E>(it: &mut I) where I: Iterator<Result<char, E>> { let mut pk = it.peekable(); loop { let cur = pk.next(); let nxt = pk.peek(); match (cur, nxt) { (Some(i), Some(nxt_i)) => println!("{} {}", i.ok(), nxt_i.ok()), _ => (), } } } fn main() { trawl(&mut std::io::stdio::stdin().chars().peekable()); }
This does not work with
> rustc /tmp/main.rs /tmp/main.rs:2:18: 2:20 error: cannot move out of dereference of `&mut`-pointer /tmp/main.rs:2 let mut pk = it.peekable(); ^~ /tmp/main.rs:7:65: 7:70 error: cannot move out of dereference of `&`-pointer /tmp/main.rs:7 (Some(i), Some(nxt_i)) => println!("{} {}", i.ok(), nxt_i.ok()), ^~~~~ note: in expansion of format_args! <std macros>:2:23: 2:77 note: expansion site <std macros>:1:1: 3:2 note: in expansion of println! /tmp/main.rs:7:39: 7:77 note: expansion site error: aborting due to 2 previous errors
Can anyone explain:
- why Peekable could not appear in the function type due to the lack of a sign,
- what does the compiler mean when it says “go from dereferencing” and
- How can I solve one or both?
Third version
fn trawl<I, E>(mut it: I) where I: Iterator<Result<char, E>> { let mut pk = it.peekable(); loop { let cur = pk.next(); let nxt = pk.peek(); match (cur, nxt) { (Some(i), Some(nxt_i)) => println!("{} {}", i.ok(), nxt_i.ok()), // (Some(i), ) => println!("{}", i.ok()), _ => (), } } } fn main() { trawl(std::io::stdio::stdin().chars().peekable()); }
This fails:
> rustc /tmp/main.rs /tmp/main.rs:7:65: 7:70 error: cannot move out of dereference of `&`-pointer /tmp/main.rs:7 (Some(i), Some(nxt_i)) => println!("{} {}", i.ok(), nxt_i.ok()), ^~~~~ note: in expansion of format_args! <std macros>:2:23: 2:77 note: expansion site <std macros>:1:1: 3:2 note: in expansion of println! /tmp/main.rs:7:39: 7:77 note: expansion site error: aborting due to previous error
I don't understand what rust says here, as Iterator.next will have a different return type from Peekable.peek.