Rust 如何使用防锈剂';什么东西可以偷看?

Rust 如何使用防锈剂';什么东西可以偷看?,rust,Rust,我对在角色流中向前窥视感兴趣。据我所知,这是一条路要走。我不太明白如何使用它 第一次尝试: 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) {

我对在角色流中向前窥视感兴趣。据我所知,这是一条路要走。我不太明白如何使用它

第一次尝试:

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());
}
fn拖网(pk:&mut I),其中I:std::iter::Peekable{
环路{
设cur=pk.next();
设nxt=pk.peek();
匹配(当前,nxt){
(Some(i),Some(nxt_i))=>println!(“{}{}”,i.ok(),nxt_i.ok()),
_ => (),
}
}
}
fn main(){
拖网(&mut std::io::stdio::stdin().chars());
}
这无法使用进行编译

> 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
>rustc/tmp/main.rs
/tmp/main.rs:1:37:1:73错误:`std::iter::Peekable`不是特征
/tmp/main.rs:1 fn拖网(pk:&mut I),其中I:std::iter::Peekable{
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
错误:由于上一个错误而中止
好的,很公平。我还没有完全理解traits,所以我尝试传入一个迭代器,然后创建一个可查看的版本:

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());
}
fn拖网(it:&muti),其中I:Iterator{
让mut pk=it.peek();
环路{
设cur=pk.next();
设nxt=pk.peek();
匹配(当前,nxt){
(Some(i),Some(nxt_i))=>println!(“{}{}”,i.ok(),nxt_i.ok()),
_ => (),
}
}
}
fn main(){
拖网(&mut std::io::stdio::stdin().chars().peek());
}
这与

> 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
>rustc/tmp/main.rs
/tmp/main.rs:2:18:2:20错误:无法移出`&mut`-指针的解引用
/tmp/main.rs:2让mut-pk=it.peek();
^~
/tmp/main.rs:7:65:7:70错误:无法移出`&`-指针的解引用
/tmp/main.rs:7(一些(i),一些(nxt_i))=>println!(“{}{}”,i.ok(),nxt_i.ok()),
^~~~~
注意:在格式参数的扩展中!
:2:23:2:77注:扩展站点
:1:1:3:2注:在println的展开中!
/tmp/main.rs:7:39:7:77注:扩建场地
错误:由于之前的两个错误而中止
谁能解释一下:

  • 为什么Peek不能出现在函数类型中,因为它不是一个特性
  • 编译器所说的“移出”和
  • 我如何解决其中一个或两个问题

第三种版本

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());
}
fn拖网(mut-it:I),其中I:Iterator{
让mut pk=it.peek();
环路{
设cur=pk.next();
设nxt=pk.peek();
匹配(当前,nxt){
(Some(i),Some(nxt_i))=>println!(“{}{}”,i.ok(),nxt_i.ok()),
//(Some(i),=>println!(“{}”,i.ok()),
_ => (),
}
}
}
fn main(){
拖网(std::io::stdio::stdin().chars().peekable());
}
这在以下情况下失败:

> 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
>rustc/tmp/main.rs
/tmp/main.rs:7:65:7:70错误:无法移出`&`-指针的解引用
/tmp/main.rs:7(一些(i),一些(nxt_i))=>println!(“{}{}”,i.ok(),nxt_i.ok()),
^~~~~
注意:在格式参数的扩展中!
:2:23:2:77注:扩展站点
:1:1:3:2注:在println的展开中!
/tmp/main.rs:7:39:7:77注:扩建场地
错误:由于上一个错误而中止

我无法理解rust在这里对我说的是什么,Iterator.next的返回类型如何与Peekable.peek不同。

Peekable
实际上是一个结构,而不是一个特性。如果您想获取一个
Peekable
,您可以这样定义您的函数:

fn trawl<E, I>(it: Peekable<I>) where I: Iterator<Result<char, E>> {
    ...
}
如果不想将迭代器移动到类似于
trawl
的函数中,可以使用
by_ref()
方法创建一个新的迭代器,该迭代器保留
&mut
引用:

fn trawl<E, I>(it: I) where I: Iterator<Result<char, E>> {
    let it = it.peekable();
    ...
}
let mut my_iterator = /* whatever */;
trawl(my_iterator.by_ref());
// my_iterator is still usable here

就风格而言,我认为第二种形式是更好的方式,因为第一种形式泄露了基本的实现细节。

Peekable
不是一种特性,因此不能用作绑定,这意味着它可能意味着多种类型中的一种。它是一种单一的、特定的、具体的类型,
struct Peekable
。正如您所观察到的,它是通过在迭代器上调用
peek()
方法构建的,该方法将其更改为可查看的内容

下面是如果您只想使用迭代器,您将如何使用它:

fn trawl<I, E>(iter: I) where I: Iterator<Result<char, E>> {
    let pk = pk.peekable();
    …
}

与前面的答案相比,锈病有了一些变化。现在的解决方法是:

fn拖网(主键:可窥视)
其中I:迭代器{
…
}

如果迭代器是按值传递给“trawl”的,那么当迭代器发生变异时,人们将如何遍历其内容?我不知道这里要做的正确事情是什么——从精神上讲——实现第二个实现的目的。如果迭代器是按值传递给
trawl
,则函数拥有它,并且可以用它做任何事情。你可以做
fn-trawl(it:I){let mut-it=it;…}
来允许在迭代器上进行迭代。还有一个在语义上完全相同的缩写:
fn-trawl(mut-it:I){…}
。未来读者注意:当这个答案被写出来时,情况已经不是这样了,但是,这个问题在2014年12月得到了解决。
fn trawl<I, E>(pk: Peekable<E, I>) where I: Iterator<Result<char, E>> {
    …
}