Rust中&Result<T, String>无法使用?运算符的问题及解决
问题分析与修正方案
问题根源
你用temp.iter()遍历得到的每个元素是&Result<T, String>类型的引用,而Rust的?运算符依赖Try trait——只有Result<T, E>本身实现了这个trait,它的引用类型&Result<T, E>并没有实现,所以直接对x?调用会触发"Try trait未为该引用类型实现"的错误。
修正方法
方式一:用into_iter()转移所有权(推荐,无需保留原Vec时)
如果后续不需要再使用temp这个Vec,直接用into_iter()遍历,拿到每个Result<T, String>的所有权,这样就能正常使用?:
Ok(temp.into_iter().map(|x| x?).collect::<Vec<T>>())
更简洁的写法是利用Result的FromIterator实现,直接让collect返回Result<Vec<T>, String>,遇到错误会自动提前返回,不用手动包Ok:
temp.into_iter().map(|x| x?).collect()
方式二:保留原Vec所有权,用as_ref()转换
如果需要保留temp的所有权,不想消耗它,可以用as_ref()把&Result<T, String>转换成Result<&T, &String>,这样就能对引用版Result使用?。之后如果需要T的所有权,根据T的特性处理:
- 若
T实现了Clone:Ok(temp.iter().map(|x| x.as_ref()?.clone()).collect::<Vec<T>>()) - 若
T是Copy类型:Ok(temp.iter().map(|x| *x.as_ref()?).collect::<Vec<T>>())
额外优化建议
其实可以把两步合并,不需要先收集成Vec<Result<T, String>>,直接在第一次迭代时处理错误,一步得到最终的Result<Vec<T>, String>,省去中间Vec的存储,性能更优:
self.value.clone() .iter() .map(|x| self.parse(x.to_string())) .collect::<Result<Vec<T>, String>>()
内容的提问来源于stack exchange,提问作者filif96770
相关产品推荐
相关产品推荐

