Rust 当包含引用时,如何返回错误?

Rust 当包含引用时,如何返回错误?,rust,borrow-checker,Rust,Borrow Checker,我有一个Rust方法,它返回一个结果。此方法在状态结构上运行,MyError具有生存期说明符'a,因为它需要保留一些&strs 我想写一个这样的特点: trait MyTrait { type Error; fn work(&self) -> Result<(), Self::Error>; } impl<'a> MyTrait for MyImpl<'a> { type Error = MyError<'a&g

我有一个Rust方法,它返回一个
结果
。此方法在
状态
结构上运行,
MyError
具有生存期说明符
'a
,因为它需要保留一些
&str
s

我想写一个这样的特点:

trait MyTrait {
    type Error;

    fn work(&self) -> Result<(), Self::Error>;
}

impl<'a> MyTrait for MyImpl<'a> {
    type Error = MyError<'a>;

    fn work(&self) -> Result<(), MyError<'a>> {
        let state = State::new();

        state.work() // returns Result<(), MyError> but state doesn't live long enough
    }
}

()

问题在于,根据
State::work()
的签名,
MyError
的生存期参数与
&self
引用的生存期参数相关联:

// without lifetime elision
pub fn work<'a>(&'a self) -> Result<(), MyError<'a>>
问题是,
impl
中的生存期参数
'a
表示的生存期严格大于
State::work()
返回的
MyError
的生存期。为什么会这样?好了,让我们再看看
MyImpl::work()

fn work(&self) -> Result<(), MyError<'a>> {
    let state = State::new();
    state.work()
}
现在,
MyError
值的生存期正好是
self.some\u string
的生存期,借阅检查器变得高兴起来

现在,有什么选择?首先,最简单的方法是将拥有的
字符串
存储在
MyError
中:

enum MyError {
    Some(String)
}

impl<'a> MyTrait for MyImpl<'a> {
    type Error = MyError;

    fn work(&self) -> Result<(), MyError> {
        let state = State::new();
        state.work()
    }
}

struct State;

impl State {
    pub fn new() -> State {
        State
    }

    pub fn work(&self) -> Result<(), MyError> {
        Err(MyError::Some("hi".into()))
    }
}

这种方法不允许您动态地创建错误消息(您只能对错误消息使用字符串文字),但它更有效,因为它不需要为程序中不愉快的路径分配,并且对于您的用例来说可能就足够了。

问题在于根据
State::work的签名()
MyError
的生存期参数与
&self
参考的生存期参数绑定:

// without lifetime elision
pub fn work<'a>(&'a self) -> Result<(), MyError<'a>>
问题是,
impl
中的生存期参数
'a
表示的生存期严格大于由
State::work()
返回的
MyError
的生存期。为什么会这样?好吧,让我们再看看
MyImpl::work()

fn work(&self) -> Result<(), MyError<'a>> {
    let state = State::new();
    state.work()
}
现在,
MyError
值的生存期正好是
self.some\u string
的生存期,借阅检查器变得高兴起来

现在,有哪些选项?首先,最简单的方法是在
MyError
中存储一个拥有的
String

enum MyError {
    Some(String)
}

impl<'a> MyTrait for MyImpl<'a> {
    type Error = MyError;

    fn work(&self) -> Result<(), MyError> {
        let state = State::new();
        state.work()
    }
}

struct State;

impl State {
    pub fn new() -> State {
        State
    }

    pub fn work(&self) -> Result<(), MyError> {
        Err(MyError::Some("hi".into()))
    }
}

这种方法不允许动态创建错误消息(只能对错误消息使用字符串文字)但是它更有效,因为它不需要为程序中不愉快的路径分配资源,而且对于您的用例来说可能已经足够了。

您也没有提供
MyError
的定义以及
State::work()的确切定义
创建
MyError
。如果它确实包含绑定到
state
生存期的字符串片段,则无法返回
MyError
,因为
state
MyImpl::work()中被销毁
@VladimirMatveev这显然是个问题,但是我如何将它们绑定到
MyError
呢?您也没有提供
MyError
的定义以及如何准确地
State::work()
创建
MyError
。如果它确实包含绑定到
state
生存期的字符串片段,则无法返回
MyError
,因为
state
MyImpl::work()中被销毁
@VladimirMatveev这显然是个问题,但我如何将它们绑定到
MyError
enum MyError {
    Some(&'static str)
}

struct State;

impl State {
    pub fn new() -> State {
        State
    }

    pub fn work(&self) -> Result<(), MyError> {
        Err(MyError::Some("hi"))
    }
}