我正在尝试在枚举上实现std::error::Error
特征。枚举的一些元素是Enum Variants,我想生成一个包含变体数据的不同错误消息。但是,如果String
到Deref
的格式化&str
下面的实现时间不够长。
一般解决方案是返回String
。但是,这不是一个选项,因为返回的类型必须是&str
特征指定的Error
。
重要的是要注意变体可能不包含usize,而可能是另一个枚举或结构等。
use std::fmt;
use std::fmt::{Display, Formatter};
use std::error;
#[derive(Debug)]
enum EnumError {
A,
B(usize),
C(usize),
D,
}
impl error::Error for EnumError {
fn description(&self) -> &str {
use EnumError::*;
match *self {
A => "A happened",
B(value) => &*format!("B happened info: {:?}", value),
C(value) => &*format!("B happened info: {:?}", value),
D => "D happened",
}
}
}
impl Display for EnumError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
use std::error::Error;
write!(f, "{}", self.description())
}
}
fn main() {}
答案 0 :(得分:4)
您创建的字符串需要由某些东西拥有。在方法中创建本地字符串时,必须将其所有权转移给调用方。但由于你必须返回&str
,这不是一个选项。
绕过它的方法是将字符串存储在结构本身中。您可以将枚举值声明为B(usize, String)
,在创建时将描述放在那里,然后使用
B(_, ref descr) => descr
坦率地说,描述不应该是一个非常详细的消息,它只需要对这是什么类型的错误给出一般描述,这就是它返回&str
的原因。我没有看到将任何动态数据写入标准库中的描述的实例,通常它只是一个静态字符串。 Display
实现是另一回事,在那里你可以更加冗长。