包含引用时如何 return 一个错误?
How to return an Error when it contains a reference?
我有一个 returns 一个 Result<_, MyError>
的 Rust 方法。此方法在 State
结构上 运行 并且 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
}
}
如何解决这个错误?我应该更改 MyError
以保留 String
而不是 &'a str
吗?我应该把 state
放在 MyImpl
里面吗?这trait
定义明确吗?
我想为 do()
的每个 运行 创建一个 State
。
这是一个 MCVE:
enum MyError<'a> {
Some(&'a str),
}
trait MyTrait {
type Error;
fn work(&self) -> Result<(), Self::Error>;
}
struct MyImpl<'a> {
pub some_string: &'a str,
}
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
}
}
struct State;
impl State {
pub fn new() -> State {
State
}
pub fn work(&self) -> Result<(), MyError> {
Err(MyError::Some("hi"))
}
}
fn main() {}
问题是,根据 State::work()
的签名,MyError
的生命周期参数与 &self
的生命周期参数相关联参考:
// without lifetime elision
pub fn work<'a>(&'a self) -> Result<(), MyError<'a>>
然后这个值被 returned in MyImpl::work()
:
fn work(&self) -> Result<(), MyError<'a>> {
let state = State::new();
state.work()
}
问题是,impl<'a> MyTrait for MyImpl<'a>
中的生命周期参数 'a
表示生命周期严格大于 MyError
[=62] =]由 State::work()
编辑。为什么会这样?好吧,让我们再看看MyImpl::work()
:
fn work(&self) -> Result<(), MyError<'a>> {
let state = State::new();
state.work()
}
请记住 State::work(&self)
return 是一个 MyError
的生命周期与 &self
的生命周期相关联,也就是说,在这种特殊情况下,它将是 [= 的生命周期28=]。后者是局部变量,在 work()
returns.
之后立即销毁
然而,impl<'a> MyTrait for MyImpl<'a>
中的'a
表示存储在MyImpl
(即self
中)的字符串切片的生命周期。自然地,因为 MyImpl::work()
可以被调用,这意味着它被调用的值处于有效状态并且包含一个活跃的切片。因此,它的生命周期比 MyImpl::work()
中可以创建的任何东西都长。所以 return 任何不是从 MyImpl
中的这个字符串切片派生的东西都是不合理的;例如,这是有效的:
impl<'a> MyTrait for MyImpl<'a> {
type Error = MyError<'a>;
fn work(&self) -> Result<(), MyError<'a>> {
Err(MyError::Some(self.some_string))
}
}
现在 MyError
值的生命周期正好是 self.some_string
的生命周期,借用检查器变得很高兴。
现在,有哪些选择?首先,最简单的方法是将拥有的 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()))
}
}
我认为这是最惯用且最灵活的方法。具有非自给自足的错误值实际上是非常罕见的;我想我以前从未见过。另一种选择是使用 &'static str
:
enum MyError {
Some(&'static str)
}
struct State;
impl State {
pub fn new() -> State {
State
}
pub fn work(&self) -> Result<(), MyError> {
Err(MyError::Some("hi"))
}
}
此方法不允许您动态创建错误消息(您只能为错误消息使用字符串文字)但它更有效,因为它不需要为程序中的不愉快路径分配内存,并且它可能足以满足您的用例。
我有一个 returns 一个 Result<_, MyError>
的 Rust 方法。此方法在 State
结构上 运行 并且 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
}
}
如何解决这个错误?我应该更改 MyError
以保留 String
而不是 &'a str
吗?我应该把 state
放在 MyImpl
里面吗?这trait
定义明确吗?
我想为 do()
的每个 运行 创建一个 State
。
这是一个 MCVE:
enum MyError<'a> {
Some(&'a str),
}
trait MyTrait {
type Error;
fn work(&self) -> Result<(), Self::Error>;
}
struct MyImpl<'a> {
pub some_string: &'a str,
}
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
}
}
struct State;
impl State {
pub fn new() -> State {
State
}
pub fn work(&self) -> Result<(), MyError> {
Err(MyError::Some("hi"))
}
}
fn main() {}
问题是,根据 State::work()
的签名,MyError
的生命周期参数与 &self
的生命周期参数相关联参考:
// without lifetime elision
pub fn work<'a>(&'a self) -> Result<(), MyError<'a>>
然后这个值被 returned in MyImpl::work()
:
fn work(&self) -> Result<(), MyError<'a>> {
let state = State::new();
state.work()
}
问题是,impl<'a> MyTrait for MyImpl<'a>
中的生命周期参数 'a
表示生命周期严格大于 MyError
[=62] =]由 State::work()
编辑。为什么会这样?好吧,让我们再看看MyImpl::work()
:
fn work(&self) -> Result<(), MyError<'a>> {
let state = State::new();
state.work()
}
请记住 State::work(&self)
return 是一个 MyError
的生命周期与 &self
的生命周期相关联,也就是说,在这种特殊情况下,它将是 [= 的生命周期28=]。后者是局部变量,在 work()
returns.
然而,impl<'a> MyTrait for MyImpl<'a>
中的'a
表示存储在MyImpl
(即self
中)的字符串切片的生命周期。自然地,因为 MyImpl::work()
可以被调用,这意味着它被调用的值处于有效状态并且包含一个活跃的切片。因此,它的生命周期比 MyImpl::work()
中可以创建的任何东西都长。所以 return 任何不是从 MyImpl
中的这个字符串切片派生的东西都是不合理的;例如,这是有效的:
impl<'a> MyTrait for MyImpl<'a> {
type Error = MyError<'a>;
fn work(&self) -> Result<(), MyError<'a>> {
Err(MyError::Some(self.some_string))
}
}
现在 MyError
值的生命周期正好是 self.some_string
的生命周期,借用检查器变得很高兴。
现在,有哪些选择?首先,最简单的方法是将拥有的 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()))
}
}
我认为这是最惯用且最灵活的方法。具有非自给自足的错误值实际上是非常罕见的;我想我以前从未见过。另一种选择是使用 &'static str
:
enum MyError {
Some(&'static str)
}
struct State;
impl State {
pub fn new() -> State {
State
}
pub fn work(&self) -> Result<(), MyError> {
Err(MyError::Some("hi"))
}
}
此方法不允许您动态创建错误消息(您只能为错误消息使用字符串文字)但它更有效,因为它不需要为程序中的不愉快路径分配内存,并且它可能足以满足您的用例。