【问题标题】:Cannot move io::Error out of Peekable Result无法将 io::Error 移出 Peekable Result
【发布时间】:2021-01-30 13:54:28
【问题描述】:

我只是想传播 IO 错误:

enum MyError {
    EOF,
    IO(std::io::Error),
}

fn peek_byte<R>(mut p: Peekable<Bytes<R>>) -> Result<u8, MyError>
where
    R: Read,
{
    match p.peek() {
        None => Err(MyError::EOF),
        Some(Err(e)) => Err(MyError::IO(*e)),  // <==== error is here
        Some(Ok(byte)) => Ok(*byte),
    }
}

但是,我收到以下错误:

error[E0507]: cannot move out of `*e` which is behind a shared reference
  --> src/main.rs:17:41
   |
17 |         Some(Err(e)) => Err(MyError::IO(*e)),
   |                                         ^^ move occurs because `*e` has type `std::io::Error`, which does not implement the `Copy` trait

我其实明白这一切。我知道为什么会出现错误,以及错误的含义。我不知道的是如何完成我的任务并将 IO 错误传播到我的错误类型中。

我尝试过e*ee.clone()*e.clone()*(e.clone()),但它们都产生“类型不匹配”或“无法移动”错误。

【问题讨论】:

    标签: error-handling rust iterator borrow-checker ownership


    【解决方案1】:

    Peekable 迭代器拥有其内部迭代器的下一个值的所有权,并通过peek 返回引用,但如果你真的想要拥有的值,你只需像往常一样调用next(它确实推进了迭代器,但我认为在这种情况下没关系,因为您实际上并没有使用迭代器中的任何内容,而只是试图返回错误):

    use std::io;
    use std::io::Bytes;
    use std::io::Read;
    use std::iter::Peekable;
    
    enum MyError {
        EOF,
        IO(io::Error),
    }
    
    fn peek_byte<R>(mut p: Peekable<Bytes<R>>) -> Result<u8, MyError>
    where
        R: Read,
    {
        match p.peek() {
            None => Err(MyError::EOF),
            Some(Err(e)) => Err(MyError::IO(p.next().unwrap().unwrap_err())),
            Some(Ok(byte)) => Ok(*byte),
        }
    }
    

    playground

    【讨论】:

    • 我曾想过,但我不确定 next() 是否会始终返回与 peek() 相同的值。 (如果错误情况消失了怎么办?)不过,这似乎是解决我的问题的好方法。谢谢!
    • next() 总是返回与peek() 相同的值,因为Peekable 保存了该值。 Rust 中的错误只是普通数据,就像其他任何东西一样,即使导致错误的潜在情况消失 Peekable 仍将保留原始错误实例。
    猜你喜欢
    • 2013-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多