Interesuje mnie podglądanie w strumieniu postaci. Według mojej wiedzy, Peekable byłaby drogą do zrobienia. Nie mogę całkiem wymyślić, jak z niego korzystać.Jak korzystać z Peekable Rusta?
Pierwsza próba:
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());
}
To nie skompilować z
> 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
Dobra, dość fair. Nie w pełni zrozumieć cechy jeszcze więc staram się przekazać iterator i następnie utworzyć peekable wersję:
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());
}
zawiedzie to z
> 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
Może ktoś wyjaśnić:
- dlaczego Peekable nie może pojawić się w typie funkcji z powodu braku bycia cechą,
- co oznacza kompilator, gdy mówi "wyprowadzić się z dereferencji" i
- Jak mogę rozwiązać jedno lub oba?
Trzecia wersja
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());
}
ten nie powiedzie się z:
> 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
ja nie rozumiem, co rdza mówi do mnie tutaj, jak Iterator.next miałoby inny typ zwrotu z Peekable.peek.
Nie wiedziałem tego o stdin. Dziękuję Ci. – troutwine
Uwaga dla przyszłych czytelników: kiedy ta odpowiedź została napisana, ['stdin()' było trudne do bezpiecznego użytkowania] (https://github.com/rust-lang/rust/issues/14434). Nie ma to już miejsca, ponieważ problem został rozwiązany w grudniu 2014 r. – kiwidrew