Result<T, E>.as_ref()
会将其转换为Result<&T, &E>
,但预期结果为Result<&T, E>
。
如果您想在函数中进行转换,函数必须通过引用获取Result。这是因为,为了在结果类型中使用&T
,必须在至少一个参数中有引用(这样返回的引用才能有生存期(。这将在Err
的情况下带来问题,在这种情况下,理想情况下您希望使用原始Result,但不允许这样做,因为您是通过引用获得的。如果你可以不需要E: Clone
,那么这将起作用:
pub fn convert_and_return<T, E: Clone>(r: &Result<T, E>) -> Result<&T, E> {
match r {
Ok(t) => Ok(t),
Err(e) => Err(e.clone()),
}
}
另一种可能性是要求E
实现Default
,在这种情况下,您可以从原始Result
中提取Err(e)
,并保留默认值:
pub fn convert_and_return<T, E: Default>(r: &mut Result<T, E>) -> Result<&T, E> {
match r {
Ok(t) => Ok(t),
Err(e) => Err(std::mem::take(e)),
}
}
如果您不需要在函数中提取转换,而只想就地转换Result,则不需要E
的任何特性。你可以根据条件使用结果,也可以不使用,借用检查器会允许它
pub fn convert_and_use<T, E>(r: Result<T, E>) {
let _r: Result<&T, E> = match r {
Ok(ref v) => Ok(v),
Err(e) => Err(e),
};
// use it here...
}