#[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{})
}
在上面的代码中,如果Result确定,我想打印项目的值(否则返回Err)。但是(*item)?
部分由于将值移到共享引用后面而导致错误:
[rustc E0507] [E]无法移动
*item
到共享引用移动的后面,因为它*item
具有typestd::result::Result<tests::S, tests::E>
,但没有实现Copy
特征
我曾尝试克隆数据,但不能解决问题。此外,克隆听起来不正确。
正确的解决方法/最佳做法是什么?
可以格式化引用(例如&S
)。但是,?
操作员需要在Result中返回错误,因此您必须复制,克隆或移动它:
如果Copy
为您的类型实现特征,则可以取消引用&Result<S, E>
(游乐场):
#[derive(Debug, Copy, Clone)]
struct S {}
#[derive(Debug, Copy, Clone)]
struct E {}
如果实现了错误类型Copy
,但也不能使ok类型(操场)实现,则也可以使其工作。
如果需要将引用转换为not的拥有类型,则必须克隆类型Copy
。示例(操场):
#[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);
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句