Rust中对引用调用clone()无法获得所有权对象的问题求助
问题原因与解决方案
问题根因
- 你调用
Vec::iter()得到的是共享引用迭代器,迭代产生的每个元素类型为&Item而非Item。 - Rust 为所有不可变引用
&T默认实现了Clonetrait,对&Item直接调用clone()方法时,走的是引用类型的克隆实现,返回值依然是&Item,而非你想要的所有权结构体实例,所以才会出现类型不匹配的报错。 - 额外注意:你当前的
Item结构体没有派生Clonetrait,就算正确调用了结构体的克隆方法也会编译失败。
解决方案
你可以任选以下任意一种写法修复问题,首先需要给Item结构体添加Clone派生:
#[derive(Clone)] struct Item { name: String, }
写法1:主动解引用后克隆
在调用clone前先对引用解引用,明确是对底层Item实例执行克隆:
fn get_enumerated(data: &Vec<Item>) -> Vec<(usize, Item)> { data.iter() .enumerate() .map(|(i, item)| (i, (*item).clone())) .collect() }
写法2:使用to_owned方法
ToOwned trait 对引用类型的实现会直接返回所有权对象,写法上比解引用克隆更简洁:
fn get_enumerated(data: &Vec<Item>) -> Vec<(usize, Item)> { data.iter() .enumerate() .map(|(i, item)| (i, item.to_owned())) .collect() }
写法3:使用cloned迭代器适配器
直接用cloned适配器批量把迭代器中的所有引用转为克隆后的所有权对象,不需要在map中手动处理克隆逻辑:
fn get_enumerated(data: &Vec<Item>) -> Vec<(usize, Item)> { data.iter() .cloned() .enumerate() .collect() }
内容的提问来源于stack exchange,提问作者Djent
相关产品推荐
相关产品推荐

