如何在需要返回& str的特征函数内延长字符串的生命周期?

时间:2016-01-16 14:38:38

标签: enums rust

问题

我正在尝试在枚举上实现std::error::Error特征。枚举的一些元素是Enum Variants,我想生成一个包含变体数据的不同错误消息。但是,如果StringDeref的格式化&str下面的实现时间不够长。

一般解决方案是返回String。但是,这不是一个选项,因为返回的类型必须是&str特征指定的Error

示例:Playground link

重要的是要注意变体可能不包含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() {}

1 个答案:

答案 0 :(得分:4)

您创建的字符串需要由某些东西拥有。在方法中创建本地字符串时,必须将其所有权转移给调用方。但由于你必须返回&str,这不是一个选项。

绕过它的方法是将字符串存储在结构本身中。您可以将枚举值声明为B(usize, String),在创建时将描述放在那里,然后使用

返回它
B(_, ref descr) => descr

坦率地说,描述不应该是一个非常详细的消息,它只需要对这是什么类型的错误给出一般描述,这就是它返回&str的原因。我没有看到将任何动态数据写入标准库中的描述的实例,通常它只是一个静态字符串。 Display实现是另一回事,在那里你可以更加冗长。