当前函数签名
clone_if
与你想要实现的目标不兼容。所以我稍微重写了一下,可能是为了符合你真正想要的。
干得好:
fn clone_if<List, ItemType, BinaryPredicate>(list: &List, binary_predicate: BinaryPredicate) -> List
where
for<'a> &'a List: IntoIterator<Item = &'a ItemType>,
List: FromIterator<ItemType>,
ItemType: Clone,
BinaryPredicate: Fn(&ItemType) -> bool,
{
list.into_iter()
.filter(|val| binary_predicate(*val))
.cloned()
.collect()
}
fn main() {
let first_list = vec![1, 2, 3, 4, 5, 6];
let second_list = clone_if(&first_list, |item| (item & 1) == 0);
assert_eq!(vec![2, 4, 6], *second_list);
}
说明:
-
list: &List
-用你的方式称呼它
main
,你需要一个参考。
-
for<'a> &'a List: IntoIterator<Item = &'a ItemType>
-你想要
list
引用在迭代时产生对其元素的引用,这就是
&Vec
is compatible with
。这可以防止不必要的复制。
-
List: FromIterator<ItemType>
-需要通过以下方式产生输出值
collect()
.
-
ItemType: Clone
-您希望在输出列表中创建输入项的克隆。
-
所有其他
Clone
和
Copy
s被删除了,因为它们是不必要的。
然后是算法本身:
-
.into_iter()
-创建一个
Iterator<Item = &ItemType>
从您的输入列表中
-
.filter(|val| binary_predicate(*val))
-进行筛选。尚未制作副本。需要闭包和解引用的原因是
filter
引用迭代过的项,在本例中为
&&ItemType
。因此需要一个小包装来转换
&&项目类型
到
&ItemType
,这就是
binary_predicate
需要。
-
.cloned()
-克隆所有迭代过的项目。这将转换
迭代器<项目=&项目类型>
到a
Iterator<Item = ItemType>
请注意,此操作已完成
之后
filter()
以防止复制无论如何都会被过滤掉的项目。
-
.collect()
使用
FromIterator
转换
迭代器<项目=项目类型>
到
List
.