当实现自定义错误枚举时,io::Error: Clone的特性限定未被满足。

5

当我实现自定义错误类型时,我收到了以下错误:

the trait bound `std::io::Error: std::clone::Clone` is not satisfied

这是我的自定义错误枚举:

use std::fmt;
use std::io;
use crate::memtable::Memtable;

// Define our error types. These may be customized for our error handling cases.
// Now we will be able to write our own errors, defer to an underlying error
// implementation, or do something in between.
#[derive(Debug, Clone)]
pub enum MemtableError {
    Io(io::Error),
    FromUTF8(std::string::FromUtf8Error),
    NotFound,
}

// Generation of an error is completely separate from how it is displayed.
// There's no need to be concerned about cluttering complex logic with the display style.
//
// Note that we don't store any extra info about the errors. This means we can't state
// which string failed to parse without modifying our types to carry that information.
impl fmt::Display for MemtableError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Some error occurred!");
        Ok(())
    }
}

// a test function that returns our error result
fn raises_my_error(memtable: Memtable, key: String) -> Result<(),MemtableError> {
    match memtable.read(key) {
        Ok(v) => Ok(()),
        Err(e) => Err(e),
    }
}

我做错了什么?我尝试跟随这些示例:
  1. https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/define_error_type.html
  2. https://learning-rust.github.io/docs/e7.custom_error_types.html
  3. https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/wrap_error.html
2个回答

6

在你的MemtableError枚举中,你使用了不实现Clonestd::io::error(这就是错误信息所说的)。你也应该会收到关于std::string::FromUtf8Error的同样错误。

为了解决这个问题,你可以从derive-macro中删除Clone。或者你需要显式地在你的错误类型上实现Clone。然而,在当前的设置中,这种方法不起作用,因为io::Error在内部使用了一个trait对象(Box<dyn Error + Send + Sync>)。而这个trait对象无法被克隆。请参见这个issue。一个解决方法是将std::io::Errorstd::string::FromUtf8Error放入一个RcArc中:

#[derive(Debug, Clone)]
pub enum MemtableError {
    Io(std::rc::Rc<io::Error>),
    FromUTF8(std::rc::Rc<std::string::FromUtf8Error>),
    NotFound,
}

为了确定这是否是解决此问题的合理方法,我们需要了解您代码的其他部分。
因此,最简单的修复方法是删除Clone。否则,请使用Rc/Arc

1
错误发生是因为您试图为MemtableError派生Clone实现,但std :: io :: Error(您的MemtableError可以存储的值之一的类型)本身并没有实现Clone。如果不需要克隆,则建议将其更改为简单的#[derive(Debug)]。否则,我们需要更多关于您使用情况的上下文来建议更具体的修复方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接