#[derive(Debug)]
struct S{}
#[derive(Debug)]
struct E{}
fn test() -> Result<S, E> {
let data_1: Result<S, E> = Ok(S{});
let data_2: Result<S, E> = Err(E{});
let v: Vec<Result<S, E>> = vec![data_1, data_2];
for i in 1..2 {
for item in &v {
let val = item?; //error
println!("{:?}", val);
};
}
Ok(S{})
}
在上面的代码中,如果结果是好的,我想打印项目的值(否则返回错误)。但是(*item)?
有错误部分原因是将值移到共享引用后面:
[rustc E0507] [E] cannot move out of
*item
which is behind a shared reference move occurs because*item
has typestd::result::Result<tests::S, tests::E>
, which does not implement theCopy
trait
我试过克隆数据,但没有解决问题。此外,克隆听起来不正确。
正确的解决方法/最佳实践是什么?
最佳答案
可以对引用进行格式化(例如 &S
)。然而 ?
运算符需要在结果中返回错误,因此您必须复制、克隆或移动它:
复制
如果您实现 Copy
您的类型的特征,您可以取消引用 &Result<S, E>
( playground ):
#[derive(Debug, Copy, Clone)]
struct S {}
#[derive(Debug, Copy, Clone)]
struct E {}
如果错误类型实现 Copy
,您也可以让它工作,但不是 ok 类型 ( playground )。
克隆
如果需要将引用转换为非Copy
的拥有类型,则必须克隆类型.示例 ( playground ):
#[derive(Debug, Clone)]
struct S {}
#[derive(Debug, Clone)]
struct E {}
let val = item.clone()?;
您可以将其更改为仅在出现错误时克隆 (playground):
#[derive(Debug)]
struct S {}
#[derive(Debug, Clone)]
struct E {}
let val = item.as_ref().map_err(Clone::clone)?;
移动
如果迭代后不需要矢量,可以移动它:
for item in v { // this calls `IntoIterator::into_iter(v)` implicitly
let val = item?;
println!("{:?}", val);
}
或者,您可以转换 Vec<Result<S, E>>
到 Result<Vec<S>, E>
第一:
// collects the `Ok` values, or returns the first error it encounters
let v: Vec<S> = v.into_iter().collect::<Result<_, _>>()?;
for item in &v {
println!("{:?}", item);
}
关于rust - 如果 Result 在 Vector 中,如何获得 Result 的 Ok 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61975873/